TypeScript中的 infer

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

我们直接使用ReturnType可以获取mapFn的函数返回类型:

type FnReturn = ReturnType<typeof mapFn>;
// 等价于
type FnReturn = OperatorFunction<string, { myName: string }>;
1
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

# 总结

infer 关键字让我们拥有深入展开泛型的结构,并 Pick 出其中任何位置的类型,并作为临时变量用于最终返回类型的能力。

Last Updated: 2/21/2022, 11:35:56 AM