介绍ts工具类型、使用场景以及模拟实现。
Partial<T>
1. 含义: 构造一个新类型,把类型T中的所有属性转化为可选属性
2. 示例:
interface A {
x: number ;
y: number;
}
type T = Partial<A> // {x?: numner; y?:number}
3. 模拟实现
type myPartial<T> = {
[key in keyof T]?: T[key]
}
Required<T>
1. 含义: 构造一个新类型,把类型T中的所有属性转化为必选属性
2. 示例:
interface A {
x: number ;
y: number;
}
type T = Required<A> // {x: numner; y:number}
3. 模拟实现
需要通过-?将类型变成必选的
type myRequired<T> = {
[key in keyof T]-?: T[key]
}
Readonly<T>
1. 含义: 构造一个新类型,把类型T中的所有属性转化为只读属性
2. 示例:
interface A {
x: number ;
y: number;
}
type T = Readonly<A> // { readonly x: number; readonly y:number}
const a: T = { x:0, y:0 }
a.x = 1; // 编译错误!不允许修改
3. 模拟实现
type myReadonly<T> = {
readonly [key in keyof T]: T[key]
}
Pick<T,U>
1. 含义: 从已有类型对象中挑选出给定的属性和类型
2. 示例:
interface A {
x: number ;
y: number;
z: number;
}
type T0 = Pick<A,'x'|'y'> // { x: number; y :number; }
type T1 = Pick<A,'x'> // { x: number; }
3. 模拟实现
这里再实现上需要注意的是,因为要从T中挑选U,所以U一定是T的键值的子集,这个地方要对U这个泛型做限制。
3.1 使用对象类型来表示
type myPick<T,U extends keyof T> = {
[key in U]:T[key]
}
3.2 函数字面量来表示
type myPick = <T,U extends keyof T> (obj :T, keys: U[]) => { [key in U]:T[key] }
Omit<T,U>
1. 含义: 从类型 T 中排除一组属性 K,并创建一个新类型。
2. 示例:
interface Person {
name: string;
age: number;
address: string;
}
type PersonWithoutAddress = Omit<Person, "address">; // { name: string; age: number; }
3. 模拟实现
可以通过Pick挑选出除了(Exclude)U中的属性,返回新类型。这里要注意Exclude第一项是 keyof T,而不是T。
type myOmit<T,U extends T> = myPick<T,Exclude<keyof T,U>>
Record<K,T>
1. 含义: 给出K(一组Key),类型T,返回新类型,一组Key类型都是T
2. 示例:
type StatusCodeDescriptions = Record<200 | 404 | 500, string>;
const statusDescriptions: StatusCodeDescriptions = {
200: "OK",
404: "Not Found",
500: "Internal Server Error",
};
3. 模拟实现
这里要注意的是对K的类型限制K extends keyof any。
type myRecord<K extends keyof any,T> = {
[key in K]: T
}
Exclude<T,U>
1. 含义: 从类型T中排除可以分配给类型U的属性
2. 示例:
type NonNullableValues = Exclude<string | number | null | undefined, null | undefined>; // string | number
3. 模拟实现
type myExclude = T extends U ? never : T;
ReturnType<T>
1. 含义: 获取函数类型T的返回类型
2. 示例:
function greet(name: string): string {
return `Hello, ${name}`;
}
type Greeting = ReturnType<typeof greet>; // string
3. 模拟实现
returnType需要通过使用infer关键字(infer占位结合条件类型做类型推断)结合extends来实现
infer 是 TypeScript 中的类型推断关键字,通常与条件类型一起使用。在条件类型中,我们可以使用 infer 关键字在一个类型推断位置上声明一个类型变量。然后在条件类型的真分支中,我们可以引用这个类型变量这使得 TypeScript 能够在条件类型的上下文中推断一个类型。
type myReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
InstanceType<T>
1. 含义: 获取构造函数T的返回类型
2. 示例:
class Person {
constructor(public name: string, public age: number) {}
}
type PersonInstance = InstanceType<typeof Person>; // Person
3. 模拟实现
type myInstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
NonNullable<T>
1. 含义
过滤掉Null、undefiened类型
2. 模拟实现
type NonNullable = T & {}