为什么泛型 T 仅在具有约束时才被推断为文字类型? [英] Why generic T is inferred as a literal type only when it has a constraint?

查看:24
本文介绍了为什么泛型 T 仅在具有约束时才被推断为文字类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看以下代码片段

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 中它们被推断为 numberstring,唯一的区别是约束.

As you can see the bar function infers the type of T as a literal type ('111' and 'hello' in the example) but in the function foo they are inferred as number or string, and the only difference is the constraint.

奇怪的是,如果使用盒装类型如下

Curiously, if use the boxed types as follows

declare function baz<T extends Number | String>(a: T): (b: T) => boolean;

then T 被推断为 numberstring,但它们中的一个是原始类型并且 T 被推断为文字类型:

then T is inferred as number and string, but it's enough that one of them be a primitive type and T is inferred as a literal type:

declare function brr<T extends Number | string>(a: T): (b: T) => boolean;

所以问题是: 为什么 foo('hello')T 推断为 string>bar('hello')T 推断为 'hello'?为什么它只在 T 被约束时发生(至少在这个例子中)?

So the question is: Why foo('hello') infers T as string but bar('hello') infers T as 'hello'? Why it happens only when T is constrained (in this example at least)?

推荐答案

有时,您希望为字符串文字 'hello' 推断出精确的文字类型 'hello'.有时,您希望为字符串文字 'hello' 推断出更广泛的、非特定的 string 类型.

Sometimes, you want exact literal type 'hello' inferred for string literal 'hello'. Sometimes, you want wider, non-specific string type inferred for string literal 'hello'.

规则 - 何时应该推断确切类型,何时应该扩大类型 - 经历了几次迭代,当前的实现 在此处显示:

The rules - when exact type should be inferred, and when the type should be widened - went through a couple of iterations, the current implemenation is presented here:

在调用表达式的类型参数推断期间,为类型参数 T 推断的类型扩展为其扩展的文字类型,如果:

During type argument inference for a call expression the type inferred for a type parameter T is widened to its widened literal type if:

  • 对 T 的所有推断都是对特定参数类型中 T 的顶级出现进行的,并且
  • T 没有约束或它的约束不包括原始类型或文字类型,并且
  • T 是在推理过程中固定的,或者 T 没有出现在返回类型的顶层.

这篇关于为什么泛型 T 仅在具有约束时才被推断为文字类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆