TypeScript中的 infer
JiaoXin2005 12/10/2021 TypeScript
Infer 关键字用于条件中的类型推导。
个人理解:infer 代表 泛型 的变量,用于 pick 出泛型的子集类型
Typescript 官网 (opens new window)也拿 ReturnType
这一经典例子说明它的作用:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
1
理解为:如果 T
继承了 (...args: any[]) => any
类型,则返回类型 R
, 否则返回 any
。其中 R
是什么呢?R
被定义在 extends (...args: any[]) => infer R
中,即 R
是从传入参数类型中推导出来的。
# 工作中的一个例子
在使用 RxJS 时,它会自动推断出操作符函数返回的类型。比如:
import { of, map, Observable, OperatorFunction } from "rxjs";
const mapFn = (name: string) => map((name: string) => ({ myName: name }));
1
2
3
2
3
我们直接使用ReturnType
可以获取mapFn
的函数返回类型:
type FnReturn = ReturnType<typeof mapFn>;
// 等价于
type FnReturn = OperatorFunction<string, { myName: string }>;
1
2
3
2
3
可是,我们如果只是想要map
操作符中返回的{myName: string}
这个类型,这个时候infer
就能排上用场了。
type PickType<T> = T extends OperatorFunction<string, infer R> ? R : unknown;
1
理解为:如果 T
继承 T extends OperatorFunction<string, infer R>
,那么从infer R
这个位置,推断出R
的类型。
type person = PickType<ReturnType<typeof mapFn>>;
// 等价于
type person = { myName: string };
1
2
3
2
3
# 总结
infer
关键字让我们拥有深入展开泛型的结构,并 Pick 出其中任何位置的类型,并作为临时变量用于最终返回类型的能力。