为什么仅当泛型 T 具有约束时才将其推断为文字类型?
Why generic T is inferred as a literal type only when it has a constraint?
请参阅以下代码段
declare function foo<T>(a: T): (b: T) => boolean;
foo(111)(222); // T inferred as 'number'
foo('hello')('bye'); // T inferred as 'string'
declare function bar<T extends number | string>(a: T): (b: T) => boolean;
bar(111)(222); // T inferred as '111'
bar('hello')('bye'); // T inferred as 'hello'
如您所见,bar
函数将 T
的类型推断为文字类型(示例中的 '111'
和 'hello'
),但在函数 foo
它们被推断为 number
或 string
,唯一的区别是约束。
奇怪的是,如果使用如下的盒装类型
declare function baz<T extends Number | String>(a: T): (b: T) => boolean;
然后 T
被推断为 number
和 string
,但其中一个是基本类型就足够了, T
被推断为字面量类型:
declare function brr<T extends Number | string>(a: T): (b: T) => boolean;
所以问题是: 为什么 foo('hello')
推断 T
为 string
而 bar('hello')
推断 T
作为 'hello'
?为什么它仅在 T
受到约束时发生(至少在本例中)?
有时,您需要为字符串文字 'hello'
推断出确切的文字类型 'hello'
。有时,您需要为字符串文字 'hello'
.
推断出更广泛的、非特定的 string
类型
规则 - 何时应该推断出确切的类型,何时应该扩大类型 - 经过了几次迭代,当前的实现 is presented here:
During type argument inference for a call expression the type inferred for a type parameter T is widened to its widened literal type if:
- all inferences for T were made to top-level occurrences of T within the particular parameter type, and
- T has no constraint or its constraint does not include primitive or literal types, and
- T was fixed during inference or T does not occur at top-level in the return type.
请参阅以下代码段
declare function foo<T>(a: T): (b: T) => boolean;
foo(111)(222); // T inferred as 'number'
foo('hello')('bye'); // T inferred as 'string'
declare function bar<T extends number | string>(a: T): (b: T) => boolean;
bar(111)(222); // T inferred as '111'
bar('hello')('bye'); // T inferred as 'hello'
如您所见,bar
函数将 T
的类型推断为文字类型(示例中的 '111'
和 'hello'
),但在函数 foo
它们被推断为 number
或 string
,唯一的区别是约束。
奇怪的是,如果使用如下的盒装类型
declare function baz<T extends Number | String>(a: T): (b: T) => boolean;
然后 T
被推断为 number
和 string
,但其中一个是基本类型就足够了, T
被推断为字面量类型:
declare function brr<T extends Number | string>(a: T): (b: T) => boolean;
所以问题是: 为什么 foo('hello')
推断 T
为 string
而 bar('hello')
推断 T
作为 'hello'
?为什么它仅在 T
受到约束时发生(至少在本例中)?
有时,您需要为字符串文字 'hello'
推断出确切的文字类型 'hello'
。有时,您需要为字符串文字 'hello'
.
string
类型
规则 - 何时应该推断出确切的类型,何时应该扩大类型 - 经过了几次迭代,当前的实现 is presented here:
During type argument inference for a call expression the type inferred for a type parameter T is widened to its widened literal type if:
- all inferences for T were made to top-level occurrences of T within the particular parameter type, and
- T has no constraint or its constraint does not include primitive or literal types, and
- T was fixed during inference or T does not occur at top-level in the return type.