为什么从any []到tuple的推论变成[string,string,...],而从string []的tuple推论变成['literal1','literal2',...]

时间:2018-12-20 02:44:44

标签: typescript tuples type-inference

我已阅读此答案https://stackoverflow.com/a/45486495/1108891,该答案演示了元组类型推断。经过一些实验,我遇到了这种情况。


当我们的tuple函数具有T extends string[]时,元组具有字符串文字类型。

export const tuple_0 = <T extends string[]>(...args: T): T => args;

const ALL_SUITS_0 = tuple_0('hearts', 'diamonds', 'spades', 'clubs');

type T0 = typeof ALL_SUITS_0; // ["hearts", "diamonds", "spades", "clubs"]

另一方面,对于T extends any[],元组具有 string 类型(不是文字)。

export const tuple_1 = <T extends any[]>(...args: T) => args;

const ALL_SUITS_1 = tuple_1('hearts', 'diamonds', 'spades', 'clubs');

type T1 = typeof ALL_SUITS_1; // [string, string, string, string]

为什么在后一种情况下我们丢失文字类型?


我怀疑这与类型推断允许自己采取的特异性步骤有关。也就是说,anystring一步,而string'some-string-literal'一步。类型推断只允许自己迈出一步吗?

1 个答案:

答案 0 :(得分:3)

这不一定是特定于元组的。如果类型参数具有可以包含文字类型的约束,则Typescript将为通用参数推断文字类型。此行为是由PR

引入的

从PR:

  

在调用表达式的类型实参推断期间,如果[...] TimeOfDay _nextSalah(List<SalahModel> salahs) { DateTime now = DateTime.now(); List<TimeOfDay> times = []; int currentSalah; salahs.forEach((s) => times.add(s.time)); times.add(TimeOfDay(hour: now.hour, minute: now.minute)); times.sort((a, b) => a.hour.compareTo(b.hour)); currentSalah = times.indexWhere((time) => time.hour == now.hour); return TimeOfDay(hour: times[currentSalah].hour, minute: times[currentSalah].minute); } 没有约束或约束不包括基本类型或文本类型,则将针对类型参数T推断的类型扩展为其扩展的文字类型。

在您问题的示例中,由于T是原始的,因此我们不会扩大,并且由于string不是原始的,因此我们会扩大。