# 高级类型之强大的infer关键字
infer 是工具类型和底层库中非常常用的关键字,表示在 extends 条件语句中待推断的类型变量,相对而言也比较难理解,我们不妨从一个 typescript 面试题开始:
我们之前学过 ReturnType 用于获取函数的返回类型,那么你会如何设计一个 ReturnType?
interface User {
id: number
name: string
form?: string
}
type Foo = () => User
type R1 = ReturnType<Foo> // User
@前端进阶之旅: 代码已经复制到剪贴板
# 条件类型与infer
我们先看一个简单例子:
type ParamType<T> = T extends (param: infer P) => any ? P : T;
@前端进阶之旅: 代码已经复制到剪贴板
上面例子表示,如果 T 能赋值给 (param: infer P) => any,则结果是(param: infer P) => any类型中的参数 P,否则返回为 T,infer P表示待推断的函数参数.
我们再回到开始的面试题,由于接受的函数返回类型是未知的,所以我们需要用infer P代表函数返回类型,如下:
type ReturnType<T> = T extends (...args: any[]) => infer P ? P : any;
@前端进阶之旅: 代码已经复制到剪贴板
其实TypeScript也内置了一个获取构造函数参数的工具类型:
ConstructorParameters<T>– 提取构造函数中参数类型
class TestClass {
constructor(public name: string, public age: number) {}
}
type R2 = ConstructorParameters<typeof TestClass> // [string, number]
@前端进阶之旅: 代码已经复制到剪贴板
我们再试着把它实现一下:
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any
? P
: never;
@前端进阶之旅: 代码已经复制到剪贴板
我们一步步分析一下这个工具类型:
new (...args: any[]指构造函数,因为构造函数是可以被实例化的.infer P代表待推断的构造函数参数,如果接受的类型T是一个构造函数,那么返回构造函数的参数类型P,否则什么也不返回,即never类型
# infer的应用
infer非常强大,由于它的存在我们可以做出非常多的骚操作.
- tuple转union,比如
[string, number] -> string | number:
