这些工具函数定义在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) => void
type 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
,需要加省学习