当前位置: 首页 > news >正文

TypeScript 类型映射讲解

TypeScript 的类型映射(Mapped Types)是一种高级类型操作工具,允许开发者基于现有类型动态生成新类型。

一、基础概念

什么是类型映射

类型映射通过遍历现有对象的键(属性名),对每个属性进行转换、生成新的类型。其语法基于索引签名扩展,结合keyof和泛型实现类型推导。

举例:

type OptionsFlags<T> = {[K in keyof T]: boolean;
};

此代码将任意对象类型T的所有属性值改为布尔类型。

二、核心语法与功能

1. 基本语法

  • 遍历键集合:使用 [K in keyof T] 语法遍历 T 的所有属性名。
  • 值类型转换:对每个属性 K 的值进行重新定义,如 T[K] 或转换后的类型。

举例:复制类型

type Original = { a: number; b: string };
type Copy = { [K in keyof Original]: Original[K] }; // 等同于 Original

2. 修饰符操作

类型映射可以修改属性的特性(可选性、只读性):

  • 添加修饰符:使用 +? 或 +readonly(可简写为 ? 和 readonly) 。
     
  • 移除修饰符:使用 -? 或 -readonly

举例:移除可选性

type Concrete<T> = {[K in keyof T]-?: T[K];
};
type MaybeUser = { id?: string; name?: string };
type User = Concrete<MaybeUser>; // { id: string; name: string }

3. 键名重映射( Key Remapping 

通过 as 关键词重命名键,常结合模板字面量或工具类型(如 Capitalize)实现复杂转换。

举例:生成Getters类型

type Getters<T> = {[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface Person { name: string; age: number; }
type LazyPerson = Getters<Person>; 
// { getName: () => string; getAge: () => number }

4. 属性过滤

通过条件类型过滤特定属性:

type Filter<T> = {[K in keyof T as T[K] extends string ? K : never]: string;
};
type User = { name: string; age: number }; 
type FilteredUser = Filter<User>; // { name: string }

5. 联合类型映射

可将联合类型转换为对象类型:

type Shape = { kind: "square"; x: number } | { kind: "circle"; radius: number };
type EventMap<T extends { kind: string }> = {[E in T as E["kind"]]: (event: E) => void;
};
type Config = EventMap<Shape>; 
// { square: (e: { kind: "square"; x: number }) => void; circle: ... }

三、内置工具类型

TypeScript 提供了多个基于映射类型的工具类型,这里简单列举几个,想更详细了解可以去看我的前置文章《解读TypeScript 类型工具》。

  1. Partial<T>:所有属性变为可选。
  2. Required<T>:移除属性可选性。
  3. Record<K, V>:生成键为 K、值为 V 的类型 。

举例:

type Partial<T> = {[K in keyof T]?: T[K];
};

四、实际场景应用

1. 动态生成类型适配器

例如将api响应转换为前端组件需要的格式:

type APIResponse = { id: number; title: string; content: string };
type UIComponentProps = {[K in keyof APIResponse as `data-${K}`]: APIResponse[K];
};
// 结果:{ data-id: number; data-title: string; data-content: string }

2. 统一权限管理

将配置类型自动转换为权限类型:

type AppConfig = { username: string; layout: string };
type AppPermissions = {[K in keyof AppConfig as `change${Capitalize<K>}`]: boolean;
};
// { changeUsername: boolean; changeLayout: boolean }

3. 第三方库类型扩展

为 DOM 元素添加自定义属性:

type ElementAttributes = { id: string; class: string };
type CustomElement<T> = {[K in keyof T as `data-${string & K}`]: T[K];
} & ElementAttributes;

相关文章:

  • 基于IBM BAW的Case Management进行项目管理示例
  • day26 Python 自定义函数
  • Ubuntu服务器开启SNMP服务 监控系统配置指南 -优雅草星云智控简易化操作
  • Python类的力量:第五篇:魔法方法与协议——让类拥有Python的“超能力”
  • pytorch nn.RNN demo
  • 软件设计师考试《综合知识》设计模式之——工厂模式与抽象工厂模式考点分析
  • 【HTML】个人博客页面
  • 【美团】后端一面复盘|项目驱动 + 手撕 + JVM + 数据库全面覆盖
  • QT 使用QPdfWriter和QPainter绘制PDF文件
  • Parsec解决PnP连接失败的问题
  • 11 web 自动化之 DDT 数据驱动详解
  • Swagger go中文版本手册
  • 【HCIA】策略路由
  • 搭建Hadoop集群standalone
  • STM32 SD卡拔插后FatFs挂载失败可能原因
  • 短视频二创App功能深度解析:短剧创作与推广的智能化革命
  • 开源模型应用落地-模型上下文协议(MCP)-Resources-资源的使用逻辑
  • Python中plotext 库详细使用(命令行界面中直接绘制各种图形)
  • 前馈神经网络回归(ANN Regression)从原理到实战
  • 从单线程到多线程:项目实战web Worker线程使用总结
  • 特朗普再提“接管”加沙,要将其变为“自由区”
  • 四川甘孜炉霍县觉日寺管委会主任呷玛降泽被查
  • 董军在第六届联合国维和部长级会议上作大会发言
  • 病重老人被要求亲自取钱在农业银行门口去世?株洲警方介入
  • 金砖国家召开经贸联络组司局级特别会议,呼吁共同抵制单边主义和贸易保护主义
  • “女硕士失踪13年生两孩”案进入审查起诉阶段,哥哥:妹妹精神状态好转