持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
infer
- 啥是
infer?infer是在泛型约束的extends条件语句中起到声明占位符作用的关键字。 - 示例
extends条件语句就类似于三元运算type ExtendsExample<T> = T extends object ? T : string; // 这里因为{}是object的子类型,满足条件语句,所以a的最终类型为{} type a = ExtendsExample<{}> // 这里因为boolean不是object的子类型,不满足条件语句, // 所以a的最终类型为string type b = ExtendsExample<boolean>- 声明参数类型占位符
type InferExample<T> = T extends (param: infer P) => void ? P : T; // 满足条件语句, 且在这里占位符P的类型为promise<number>, // 所以这里的infer2,类型为promise<number> type infer1 = InferExample<(promise: Promise<number>) => void> // infer2类型为string,即传入的泛型T类型。因为不满足条件语句 type infer2 = InferExample<string> - 声明返回值类型占位符
type InferExample2<T> = T extends () => infer P ? P : T; // 满足条件语句, 且在这里占位符P的类型为promise<number>, // 所以这里的infer2,类型为promise<number> type infer3 = InferExample2<() => Promise<number>> // infer2类型为string,即传入的泛型T类型。因为不满足条件语句 type infer4 = InferExample2<string> - 声明泛型具体化类型占位符
type InferExample3<T> = T extends Promise<infer P> ? P : T; // 满足条件语句, 且在这里占位符P的类型为number, // 所以这里的infer2,类型为number type infer5 = InferExample3<Promise<number>> // infer2类型为string,即传入的泛型T类型。因为不满足条件语句 type infer6 = InferExample3<string>
- 完善泛型工厂函数,使其能够动态传入构造器参数且传值时有相应的提示
(泛型工厂函数详情可以看)
class Tearcher { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } introduce() { console.log(`My name is ${this.name},${this.age} years old`); } } type ConstructorType<T> = new (...arg: any) => T; // 获取类构造器参数类型的工具类型,这里的T为“typeof 具体类” type GetConstructorArgsType<T extends new (...arg: any[]) => any> = T extends new (...args: infer P) => any ? P : any; // 类型为元组[name: string, age: number],Tearcher构造器的形参类型 type TearcherArgsTyped = GetConstructorArgsType<typeof Tearcher>; function createGenericityInstanceFactory< T, R extends new (...arg: any[]) => any >(Constructor: ConstructorType<T>, Params: GetConstructorArgsType<R>) { return new Constructor(...Params); } // 这里teacher实例对象的类型为Tearcher // 且第二个参数的类型必须为[name: string, age: number] const tear2 = creatInstanceFactory<Tearcher, typeof Tearcher>( Tearcher, ["张三", 14] ); tear2.introduce(); // My name is 张三,14 years old