我已经阅读了此答案https://stackoverflow.com/a/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 types(不是文字)。
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
引入的来自PR:
在呼叫表达式的类型参数推断期间,如果[...]
,则将类型参数t的类型扩大到其扩大的文字类型。T
没有约束或约束不包括原始或文字类型
在您的问题中的示例中,由于string
是原始的,我们不会扩大,并且由于any
不是原始的,因此我们会扩大。