为什么Typescript人员要创建infer关键字?根据documents的说法,这是一个如何使用它的示例:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;我不明白为什么需要这样做。为什么不能这样:
type ReturnType<T> = T extends (...args: any[]) => R ? R : any;为什么这个不起作用?为什么infer关键字是必需的?
发布于 2020-02-05 09:32:32
使用infer,编译器可以确保您显式声明了所有类型变量
type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // T1 is { b: string; }在这里,我们在MyType中声明了一个新的类型变量R,它来自T。
(请注意,infer始终在的extends子句中使用。)
现在使用未声明的类型参数可能会导致编译错误:
type MyType2<T> = T extends R2 ? R2 : never; // error, R2 undeclared如果没有infer,编译器将不会知道您是否想要引入一个要推断的额外类型变量R2 (参见第一种情况),或者R2是否只是一个意外的键入错误/拼写错误。infer的存在就是为了消除这种歧义。
更准确地说,如果省略了infer,编译器会检查T is assignable to R:
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; }发布于 2020-02-05 07:51:20
考虑以下代码:
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',并且不会出现编译错误来通知程序员该错误。对于编译器来说,这几乎在所有时间都是错误的。
发布于 2021-07-24 00:40:23
infer关键字允许您从条件类型中的另一个类型推导出一个类型。下面是一个例子:
type UnpackArrayType<T> = T extends (infer R)[] ? R: T;
type t1 = UnpackArrayType<number[]>; // t1 is numberUnpackArrayType是一种条件类型。它被理解为“如果T是(推断R)[]的子类型,则返回R。否则,返回T”。
对于类型别名t1,UnpackArrayType中的条件为真,因为number[]与(推断R)[]匹配。作为推断过程的结果,类型变量R被推断为数字类型,并且从真分支返回。推断是为了告诉编译器在UnpackArrayType的作用域中声明了一个新的类型变量R。
type t2 = UnpackArrayType<string>; //t2 is string对于t2,UnpackArrayType中的条件为false,因为字符串类型与(Infer R)[]不匹配,因此将其作为字符串返回。有关更多信息,请参阅本文。https://javascript.plainenglish.io/typescript-infer-keyword-explained-76f4a7208cb0?sk=082cf733b7fc66228c1373ba63d83187
https://stackoverflow.com/questions/60067100
复制相似问题