为什么元组推理从 any[] 变成 [string, string, ... ] 而从 string[] 变成 ['literal1', 'literal2', ... ]
Why does tuple inference from any[] become [string, string, ... ] and from string[] become ['literal1', 'literal2', ... ]
我已经阅读了这个答案 ,它演示了元组类型推断。经过一些实验,我遇到了这种情况。
当我们的 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]
为什么在后一种情况下我们会丢失文字类型?
我怀疑这与类型推断允许自己采取多少特定步骤有关。即any
距离string
一步,string
距离'some-string-literal'
一步。类型推断是否只允许自己迈出一步?
这不一定特定于元组。如果类型参数具有可以具有文字类型的约束,则 Typescript 将为泛型参数推断文字类型。此行为是由 PR
引入的
来自公关:
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
has no constraint or its constraint does not include primitive or literal types
在您问题的示例中,由于 string
是原始的,我们没有加宽,并且由于 any
不是原始的,我们确实加宽了。
我已经阅读了这个答案
当我们的 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]
为什么在后一种情况下我们会丢失文字类型?
我怀疑这与类型推断允许自己采取多少特定步骤有关。即any
距离string
一步,string
距离'some-string-literal'
一步。类型推断是否只允许自己迈出一步?
这不一定特定于元组。如果类型参数具有可以具有文字类型的约束,则 Typescript 将为泛型参数推断文字类型。此行为是由 PR
引入的来自公关:
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
has no constraint or its constraint does not include primitive or literal types
在您问题的示例中,由于 string
是原始的,我们没有加宽,并且由于 any
不是原始的,我们确实加宽了。