这些工具函数定义在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 }; // stringin
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,需要加省学习