这些工具函数定义在lib.es5.d.ts
,我的typescript
版本是3.5.2
首先需要理解几个关键概念
keyof
keyof
是typescript 2.1
新增的关键字,keyof T
返回的是T
的属性名称(键名),keyof T
的类型被认为是string
的子类
interface Person { name: string; age: number; location: string;}type K1 = keyof Person; // "name" | "age" | "location"type K2 = keyof Person[]; // "length" | "push" | "pop" | "concat" | ...type K3 = keyof { [x: string]: Person }; // string
in
in
可以遍历联合类型
interface User{ name: string; age: number; phone: number;}type d = { [p in keyof User]: string;}// type d = {// name: string;// age: string;// phone: string;// }
Mapped Types 映射类型
一个常见的任务是将一个已经存在类型中的所有属性变为可选
Person
interface Person { name: string; age: number; location: string;}
它的可选属性类型应该是:
interface PartialPerson { name?: string; age?: number; location?: string;}
应用映射类型,PartialPerson
可以写为Person
的广义转换
type Partial<T> = { [P in keyof T]?: T[P];};type PartialPerson = Partial<Person>;
Partial
Partial
就是上述映射类型的举例,能够将属性转为可选属性
type Partial<T> = { [P in keyof T]?: T[P];};
Required
将所有的属性转换为必选
type Required<T> = { [P in keyof T]-?: T[P];};
在Partial
中,多了一个?
,而这里是-?
,它的意思是将?
取掉,所以这里的每一个属性都是必选的
interface User{ name: string; age?: number; phone: number;}type r = Required<User>// type r = {// name: string;// age: number;// phone: number;// }
Readonly
将所有属性变为只读属性
type Readonly<T> = { readonly [P in keyof T]: T[P];};
readonly
表示只读属性,属性只能在初始化时赋值
Pick
从T
中取出部分属性,K
是必须是T
的键名的子枚举
type Pick<T, K extends keyof T> = { [P in K]: T[P];};
interface User{ name: string; age: number; phone: number;}type p = Pick<User,"name"|"phone">// type p = {// name: string;// phone: number;// }
Record
把K
类型转换为T
类型
type Record<K extends keyof any, T> = { [P in K]: T;};
interface User{ name: string; age: number; phone: number;}type r = Record<keyof User, string>// type r = {// name: string;// age: string;// phone: string;// }
这里需要注意的是Record<K,T>
的K
必须是联合类型,需要写上keyof
Exclude
从T
中排除U
中包含的类型
type Exclude<T, U> = T extends U ? never : T;
interface User{ name: string; age: number; phone: number;}type e = Exclude<keyof User, "age"|"phone">// type e = "name"
Extract
从T
中提取包含U
的属性
type Extract<T, U> = T extends U ? T : never;
interface User{ name: string; age: number; phone: number;}type e = Extract<keyof User, "age"|"type"|"address">// type e = "age"
Omit
构造一个类型,这个类型包含除了T
类型之外的K
类型的属性
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface User{ name: string; age: number; phone: number;}type o = Omit<User, "age">;// type o = {// name: string;// phone: number;// }
NonNullable
从T
中去掉null
和undefined
type NonNullable<T> = T extends null | undefined ? never : T;
type options = "debug" | "release" | null | undefined;type n = NonNullable<options>;// type n = "debug" | "release"
Parameters
获取函数中的参数类型的元组
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
type UserFunc = (name: string, phone: number) => voidtype a = Parameters<UserFunc>// type a = [string, number]
出现了一个新关键字infer
,infer
可以表示extends
语句中待推断的类型变量
ConstructorParameters
获取构造函数中的参数类型的元组
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
class UserClass { constructor(name:string,phone:number) {};}type a = ConstructorParameters<typeof UserClass>// type a = [string, number]
ReturnType
获取函数返回值的类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
type User = { name: string };type UserFunc = () => User;type a = ReturnType<UserFunc>// type a = {// name: string;// }
InstanceType
获取构造函数函数返回值的类型
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
class UserClass { constructor(name:string,phone:number) {};}type a = InstanceType<typeof UserClass>// type a = UserClass
这些内置工具函数的参数还是有一些不理解,有些是直接传类型,有些是传keyof
后的联合类型,有一些又是typeof
,需要加省学习