typescript使用技巧 小结 typescript lib.es5.d.ts
Partial 使泛型所有属性都可选
1 2 3 4 5 6 7 8 9 10 11 type Partial<T> = { [P in keyof T]?: T[P]; }; interface User { id: number ; age: number ; name: string ; }; type user = Partial<User>
Required 使泛型所有参数都必选, 与Partial相反
1 2 3 4 5 6 7 8 9 10 11 type Required<T> = { [P in keyof T]-?: T[P]; }; interface User { id?: number ; age?: number ; name?: string ; }; type user = Required<User>
Pick 从T中,选出K对应的属性值
1 2 3 4 5 6 7 8 9 10 11 type Pick<T, K extends keyof T> = { [P in K]: T[P]; }; interface User { id: number ; age: number ; name: string ; }; type user = Pick<User, 'id' | 'name' >
Record 创建一组键为K,类型为T的数据类型
1 2 3 4 5 6 7 8 9 10 11 type Record<K extends keyof any , T> = { [P in K]: T; }; interface User { id: number ; age: number ; name: string ; }; type user = Record<'vip1' | 'vip2' , User>
Exclude 从T中排除U的值,
1 2 3 4 5 6 7 8 9 type Exclude<T, U> = T extends U ? never : T;interface User { id: number ; age: number ; name: string ; }; type user = Exclude<keyof User, 'name' >
与Exclude相反,从T中提取可分配给U的类型
1 2 3 4 5 6 7 8 9 type Extract<T, U> = T extends U ? T : never ;interface User { id: number ; age: number ; name: string ; }; type user = Extract<keyof User, 'name' >
Omit 创建一个除了K以外的类型,
1 2 3 4 5 6 7 8 9 type Omit<T, K extends keyof any > = Pick<T, Exclude<keyof T, K>>;interface User { id: number ; age: number ; name: string ; }; type user = Omit<User, 'name' >
NonNullable 从T排除null和undefined
1 2 3 4 5 6 7 8 9 10 type NonNullable<T> = T extends null | undefined ? never : T;interface User { id?: number | null ; age: number ; name: string ; }; type id = NonNullable<User['id' ]>
Parameters 1 2 3 4 5 6 7 8 type Parameters<T extends (...args: any ) => any > = T extends (...args: infer P) => any ? P : never ;function foo (x: number ): Array <number > { return [x]; } type P = Parameters<typeof foo>;
ConstructorParameters 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type ConstructorParameters<T extends new (...args: any ) => any > = T extends new (...args: infer P) => any ? P : never ;class Person { private firstName: string ; private lastName: string ; constructor (firstName: string , lastName: string ) { this .firstName = firstName; this .lastName = lastName; } } type P = ConstructorParameters<typeof Person>;
ReturnType 1 2 3 4 5 6 7 8 type ReturnType<T extends (...args: any ) => any > = T extends (...args: any ) => infer R ? R : any ;function foo (x: number ): Array <number > { return [x]; } type P = ReturnType<typeof foo>;
InstanceType 1 2 3 4 5 6 7 8 9 10 11 12 type InstanceType<T extends new (...args: any ) => any > = T extends new (...args: any ) => infer R ? R : any ;class C { x = 0 ; y = 0 ; } type T20 = InstanceType<typeof C>; type T21 = InstanceType<any >; type T22 = InstanceType<never >; type T23 = InstanceType<string >; type T24 = InstanceType<Function >;
extends extends 可以用来继承一个类,也可以用来继承一个 interface,但还可以用来判断有条件类型:
上面的类型意思是,若 T 能够赋值给 U,那么类型是 X,否则为 Y。 原理是令 T 和 U分别为 T 和 U 的实例,并将所有类型参数替换为 any,如果 T能赋值给 U,则将有条件的类型解析成 X,否则为Y。 上面的官方解释有点绕,下面举个栗子:
1 2 3 4 5 6 type Words = 'a' |'b' |"c" ;type W<T> = T extends Words ? true : false ;type WA = W<'a' >; type WD = W<'d' >;
a 可以赋值给 Words 类型,所以 WA 为 true,而 d 不能赋值给 Words 类型,所以 WD 为 false。
typeof 在 JS 中 typeof 可以判断一个变量的基础数据类型,在 TS 中,它还有一个作用,就是获取一个变量的声明类型,如果不存在,则获取该类型的推论类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 interface Person { name: string ; age: number ; location?: string ; } const jack: Person = { name : 'jack' , age : 100 };type Jack = typeof jack; function foo (x: number ): Array <number > { return [x]; } type F = typeof foo;
Jack这个类型别名实际上就是 jack 的类型 Person,而 F 的类型就是 TS 自己推导出来的 foo 的类型 (x: number) => number[]。
keyof keyof 可以用来取得一个对象接口的所有 key 值:
1 2 3 4 5 6 7 8 9 interface Person { name: string ; age: number ; location?: string ; } type K1 = keyof Person; type K2 = keyof Person[]; type K3 = keyof { [x: string ]: Person };
in in 可以遍历枚举类型:
1 2 3 4 type Keys = "a" | "b" type Obj = { [p in Keys]: any } // -> { a: any, b: any }
上面 in 遍历 Keys,并为每个值赋予 any 类型。
infer 在条件类型语句中, 可以用 infer 声明一个类型变量并且对它进行使用, 我们可以用它获取函数的返回类型, 源码如下:
1 2 3 4 5 type ReturnType<T> = T extends ( ...args: any [] ) => infer R ? R : any ;
其实这里的 infer R 就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便之后使用。
Mutable 将 T 的所有属性的 readonly 移除:
1 2 3 type Mutable<T> = { -readonly [P in keyof T]: T[P] }
PowerPartial 内置的 Partial 有个局限性,就是只支持处理第一层的属性,如果是嵌套多层的就没有效果了,不过可以如下自定义:
1 2 3 4 5 6 type PowerPartial<T> = { [U in keyof T]?: T[U] extends object ? PowerPartial<T[U]> : T[U] };
Deferred 相同的属性名称,但使值是一个 Promise,而不是一个具体的值:
1 2 3 type Deferred<T> = { [P in keyof T]: Promise <T[P]>; };
Proxify 为 T 的属性添加代理
1 2 3 type Proxify<T> = { [P in keyof T]: { get(): T[P]; set(v: T[P]): void } };