With infer
,编译器确保您已声明所有类型变量明确地:
type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // T1 is { b: string; }
这里我们声明一个new类型变量R
in MyType
, which 被推断 https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types from T
.
(注意infer
仅在以下范围内使用extends
的条款条件类型 https://www.typescriptlang.org/docs/handbook/2/conditional-types.html.)
现在使用未声明的类型参数可能会导致编译错误:
type MyType2<T> = T extends R2 ? R2 : never; // error, R2 undeclared
Without infer
,编译器不会知道,如果你想引入一个额外的类型变量R2
这是要推断的(参见第一种情况),或者如果R2
只是一个意外的打字错误/拼写错误。infer
存在就是为了消除这种歧义。
更准确地说,编译器检查,如果T
是可分配的 https://www.typescriptlang.org/docs/handbook/type-compatibility.html to R
, when infer
被省略:
type R = { a: number }
type MyType3<T> = T extends R ? R : never; // compare T with type R
type T3 = MyType3<{b: string}> // T3 is never
注意infer R
同名类型声明的影子类型引用R
:
type R = { a: number }
type MyType4<T> = T extends infer R ? R : never;
type T4 = MyType4<{b: string}> // { b: string; }
操场 https://www.typescriptlang.org/play?#code/C4TwDgpgBASlC8UDeUCGAuKA7ArgWwCMIAnKAXwCgLRIoBZEAFXAgEYAeRgPgSkaggAPYBCwATAM5QAllgBmJWFAD8SzFggA3EgG4oAen0z5iuHOIB7PH2ot6TFgCZOPRPyEjxUmI5Wxf6lq6BkYAxlZg0gA2iiSWpAAUAOYWFmIAlLa0DMyQAMwuvO7CopJKqnCB2sR6hlDheGCoxND8AO7SwAAWsFQ0ray8OSwcSASYEsDEsklkPHWMg9JSKONQk9NYSXqU-Xx5Qw757GMTUzNzIfsyUhrVfXbDkAAshW4CJV7GCqRwFVBVXRZVrPQ65CCvU7rc5bS51VZnTbbcgUIA