首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Typescript中需要infer关键字?

为什么Typescript中需要infer关键字?
EN

Stack Overflow用户
提问于 2020-02-05 07:39:26
回答 4查看 30.7K关注 0票数 68

为什么Typescript人员要创建infer关键字?根据documents的说法,这是一个如何使用它的示例:

代码语言:javascript
复制
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

我不明白为什么需要这样做。为什么不能这样:

代码语言:javascript
复制
type ReturnType<T> = T extends (...args: any[]) => R ? R : any;

为什么这个不起作用?为什么infer关键字是必需的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-05 09:32:32

使用infer,编译器可以确保您显式声明了所有类型变量

代码语言:javascript
复制
type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // T1 is { b: string; }

在这里,我们在MyType中声明了一个新的类型变量R,它来自T

(请注意,infer始终在的extends子句中使用。)

现在使用未声明的类型参数可能会导致编译错误:

代码语言:javascript
复制
type MyType2<T> = T extends R2 ? R2 : never; // error, R2 undeclared

如果没有infer,编译器将不会知道您是否想要引入一个要推断的额外类型变量R2 (参见第一种情况),或者R2是否只是一个意外的键入错误/拼写错误。infer的存在就是为了消除这种歧义。

更准确地说,如果省略了infer,编译器会检查T is assignable to R

代码语言:javascript
复制
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的类型引用

代码语言:javascript
复制
type R = { a: number }
type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // { b: string; }

Playground

票数 57
EN

Stack Overflow用户

发布于 2020-02-05 07:51:20

考虑以下代码:

代码语言:javascript
复制
interface Example {
    foo: string
}

type GenericExample<T> = T extends Examlep ? 'foo' : 'bar';

这段代码应该导致编译错误,因为Examlep拼写错误;没有名为Examlep的类型,显然程序员打算在这里编写Example

现在假设在条件类型的extends子句中不需要infer关键字。那么上面的代码就不会给出编译错误;它将看到没有名为Examlep的类型,推断它是什么类型,然后(因为Examlep没有约束)观察到T确实为推断的类型扩展了Examlep

在这种情况下,无论T是什么,GenericExample<T>都将始终为'foo',并且不会出现编译错误来通知程序员该错误。对于编译器来说,这几乎在所有时间都是错误的。

票数 56
EN

Stack Overflow用户

发布于 2021-07-24 00:40:23

infer关键字允许您从条件类型中的另一个类型推导出一个类型。下面是一个例子:

代码语言:javascript
复制
type UnpackArrayType<T> = T extends (infer R)[] ? R: T;
type t1 = UnpackArrayType<number[]>; // t1 is number

UnpackArrayType是一种条件类型。它被理解为“如果T是(推断R)[]的子类型,则返回R。否则,返回T”。

对于类型别名t1,UnpackArrayType中的条件为真,因为number[]与(推断R)[]匹配。作为推断过程的结果,类型变量R被推断为数字类型,并且从真分支返回。推断是为了告诉编译器在UnpackArrayType的作用域中声明了一个新的类型变量R。

代码语言:javascript
复制
type t2 = UnpackArrayType<string>; //t2 is string

对于t2,UnpackArrayType中的条件为false,因为字符串类型与(Infer R)[]不匹配,因此将其作为字符串返回。有关更多信息,请参阅本文。https://javascript.plainenglish.io/typescript-infer-keyword-explained-76f4a7208cb0?sk=082cf733b7fc66228c1373ba63d83187

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60067100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档