1、函数的模式匹配
1、提取参数的类型
type GetParameters15<Func extends Function> =
Func extends (...args: infer Args) => unknown ? Args : never;
type test15=GetParameters15<(answer:boolean,count:number)=>number>
//type test15 = [answer: boolean, count: number]
2、提取返回值类型
type GetReturnType16<Func extends Function> =
Func extends (...args: any[]) => infer ReturnType
? ReturnType : never;
type test16 = GetReturnType16<(answer: boolean, count: number) => 'hello'>
//type test16 = "hello"
3、让编译器能够检查出 this 指向的错误
class Hello17 {
name: string;
constructor() {
this.name = "dong";
}
hello(this: Hello17) {
return 'hello, I\'m ' + this.name;
}
}
const test17 = new Hello17();
test17.hello();
const test17_1 = new Hello17();
//test17.hello.call({ a: 11 }); 会报错 必须是Hello17这个类
this 类型同样也可以通过模式匹配提取出来
class Hello17 {
name: string;
constructor() {
this.name = "dong";
}
hello(this: Hello17) {
return 'hello, I\'m ' + this.name;
}
}
const test17 = new Hello17();
type GetThisParameterType17_1<T>
= T extends (this: infer ThisType, ...args: any[]) => any
? ThisType
: unknown;
type test17_2 = GetThisParameterType17_1<typeof test17.hello>;
//type test17_2 = Hello17
2、构造器
构造器和函数的区别是,构造器是用于创建对象的,所以可以被 new。
通过模式匹配提取构造器的参数和返回值的类型
1、取出构造器返回的实例类型
interface Hello18 {
name: string;
}
interface Hello18Constructor {
new(name: string): Hello18;
}
//这里的 Hello18Constructor 返回的是 Hello18 类型的实例对象
//这个也可以通过模式匹配取出来
type GetInstanceType18<
ConstructorType extends new (...args: any) => any
> = ConstructorType extends new (...args: any) => infer InstanceType
? InstanceType
: any;
//类型参数 ConstructorType 是待处理的类型,通过 extends 约束为构造器类型。
//用 ConstructorType 匹配一个模式类型
//提取返回的实例类型到 infer 声明的局部变量 InstanceType 里,返回 InstanceType。
//这样就能取出构造器对应的实例类型:
type test18=GetInstanceType18<Hello18Constructor>
//type test18 = Hello18
2、提取构造器的参数类型
interface Hello18 {
name: string;
}
interface Hello18Constructor {
new(name: string): Hello18;
}
type GetConstructorParameters19<
ConstructorType extends new (...args: any) => any
> = ConstructorType extends new (...args: infer ParametersType) => any
? ParametersType
: never;
//类型参数 ConstructorType 为待处理的类型,通过 extends 约束为构造器类型。
//用 ConstructorType 匹配一个模式类型
//提取参数的部分到 infer 声明的局部变量 ParametersType 里,返回 ParametersType。
type test19 = GetConstructorParameters19<Hello18Constructor>
//type test19 = [name: string]
3、索引类型的模式匹配
1、通过模式匹配的方式提取 ref 的值的类型
type GetRefProps20<Props> =
'ref' extends keyof Props
? Props extends { ref?: infer Value | undefined }
? Value
: never
: never;
//类型参数 Props 为待处理的类型。
//通过 keyof Props 取出 Props 的所有索引构成的联合类型,
//判断下 ref 是否在其中,也就是 'ref' extends keyof Props。
//如果有 ref 这个索引的话,就通过 infer 提取 Value 的类型返回,否则返回 never。
type test20 = GetRefProps20<{ ref?: 'helloref', name: 'hello' }>
//type test20 = "helloref"
参考链接: