为什么Typescript的人要创建infer关键字?

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

我不明白为什么需要这个.为什么不能是:

type ReturnType<T> = T extends (...args: any[]) => R ? R : any;

为什么这不管用?为什么infer关键字是必要的?

推荐答案

对于infer,编译器确保您已经声明了所有类型变量explicitly:

type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // T1 is { b: string; }

Here we declare a new type variable R in MyType, which gets inferred from T.
(Note, that infer is always used within the extends clause of a conditional type.)

现在可以在未声明的结果中编译类型参数的用法:

type MyType2<T> = T extends R2 ? R2 : never; // error, R2 undeclared

如果没有infer,编译器将不知道您是否想引入一个要推断的额外类型变量R2(参见第一种情况),或者R2是否只是一个意外的键入错误/打字错误.infer的存在消除了这种模糊性.

更准确地说,如果省略infer,编译器将判断T is assignableR:

type R = { a: number }
type MyType3<T> = T extends R ? R : never; // compare T with type R
type T2 = MyType2<{b: string}> // T2 is never

请注意,infer R个相同名称的类型声明的类型引用R:

type R = { a: number }
type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // { b: string; }

Playground

Typescript相关问答推荐

对可变位置的父对象的TypScript空判断

具有条件通用props 的react 类型脚本组件错误地推断类型

Typescript问题和缩减器状态不会在单击时添加用途.属性'状态和调度'不存在于userContextType类型上'|null'

如果我有对象的Typescript类型,如何使用其值的类型?

替代语法/逻辑以避免TS变量被分配之前使用." "

如果请求是流,如何等待所有响应块(Axios)

Redux—Toolkit查询仅在不为空的情况下添加参数

如何正确地对类型脚本泛型进行限制

如何在LucideAngular 添加自定义图标以及如何使用它们

适当限制泛型函数中的记录

TypeScrip:来自先前参数的参数中的计算(computed)属性名称

如何在NX工作区项目.json中设置类似angular.json的两个项目构建配置?

类型脚本可以推断哪个类型作为参数传递到联合类型中吗?

如何在使用条件类型时使用void

类型与泛型抽象类中的类型不可比较

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

有没有一种更好的方法来存储内存中的数据,而不是在类型脚本中使用数组和基于索引的函数?

使用RXJS获取数据的3种不同REST API

如何调整项目数组,但允许权重影响顺序

为什么类方法参数可以比接口参数窄