Typescript泛型笔记之映射类型(Mapped Type)和条件类型(Conditional Types)

Typescript泛型笔记之映射类型(Mapped Type)和条件类型(Conditional Types)
最新回答
阴郁钢琴

2026-10-21 18:29:44

映射类型(Mapped Type)

映射类型是 TypeScript 中一种强大的类型构造工具,它允许你基于已有的类型创建一个新的类型,通过遍历原类型的属性并进行某种转换。其基本语法如下:

type NewType<T> = { [K in keyof T]: T[K]; // 对T的每个属性K,映射为T[K]类型};

映射类型的关键在于 in keyof 操作符,它遍历类型 T 的所有键(属性名),并对每个键应用指定的类型转换规则。

示例:将接口属性变为可选interface Person { name: string; age: number;}// 将Person的所有属性变为可选type PartialPerson = { [K in keyof Person]?: Person[K];};// 等价于type PartialPerson = { name?: string; age?: number;};示例:将接口属性变为只读type ReadonlyPerson = { readonly [K in keyof Person]: Person[K];};// 等价于type ReadonlyPerson = { readonly name: string; readonly age: number;};条件类型(Conditional Types)

条件类型允许你根据条件的判断结果选择不同的类型,其语法类似于三元表达式:

T extends U ? X : Y
  • 如果类型 T 可以赋值给类型 U(即 T 是 U 的子类型),则结果为 X,否则为 Y。
示例:NonNullable<T> 的实现type NonNullable<T> = T extends null | undefined ? never : T;
  • 如果 T 是 null 或 undefined,则结果为 never(表示排除这些类型)。
  • 否则,结果为 T 本身。
联合类型的分配律

当 T 是联合类型时,条件类型会应用分配律:

type A = NonNullable<string | number | null | undefined>;// 等价于type A = | (string extends null | undefined ? never : string) | (number extends null | undefined ? never : number) | (null extends null | undefined ? never : null) | (undefined extends null | undefined ? never : undefined);// 结果为 string | number结合映射类型和条件类型

映射类型和条件类型可以结合使用,实现更复杂的类型转换。

示例:过滤接口的特定属性interface User { id: number; name: string; age: number; password: string;}// 过滤掉password属性type OmitPassword<T> = { [K in keyof T as K extends 'password' ? never : K]: T[K];};type UserWithoutPassword = OmitPassword<User>;// 等价于type UserWithoutPassword = { id: number; name: string; age: number;};
  • as K extends 'password' ? never : K 表示:如果属性名 K 是 'password',则排除该属性(never),否则保留属性名 K。
总结
  1. 映射类型:

    用于基于已有类型创建新类型,通过遍历属性并应用转换规则。

    语法:{ [K in keyof T]: ... }。

    常见用途:生成可选类型(Partial<T>)、只读类型(Readonly<T>)等。

  2. 条件类型:

    用于根据条件选择类型,语法为 T extends U ? X : Y。

    支持分配律,可处理联合类型。

    常见用途:NonNullable<T>、ReturnType<T> 等工具类型。

  3. 结合使用:

    可以在映射类型中使用条件类型,实现更灵活的类型过滤或转换。

    示例:OmitPassword<T> 通过条件类型过滤特定属性。

通过掌握映射类型和条件类型,你可以编写更灵活、更强大的类型定义,提升代码的类型安全性。