Typescript `custom type` 仅适用于类型世界,但实际上不适用于 `function`

Typescript `custom type` only works in type world, but not actually working with `function`

我有一个名为 Tail 的自定义类型,它将 return 没有第一个元素的数组类型:

type Tail<T extends any[]> =
    ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any)
    ? TT
    : []

type test11 = Tail<[1, 2, string, number]> // [2, string, number]

上面的代码工作正常,但是当使用 with 函数时,它现在不工作了:

function tail<T extends any[]>(arr: T): Tail<T> {
  return arr.slice(1) as Tail<T>;
}

let result = tail(['', 1]); // res: (string | number)[]

result应该只有number,但是却显示(string | number)[],为什么?

Typescript specification。具体来说,它说:

The rules [given] mean that an array literal is always of an array type, unless it is contextually typed by a tuple-like type.

在您对 tail 的调用中,对 ['', 1] 类型的唯一提示是 any[]。 (见4.15.2节,我略读了一下,好像是这么说的,但是如果我错了有人可以喊我。)因此,它的类型变成(string | number)[],你调用tail 签名

tail<(string | number)[]>(arr: (string | number)[]): (string | number)[]

您可以将问题重现为

let i = ['5', 5]
let x: [number] = tail(i)

你会看到它消失在

let i: [string, number] = ['5', 5]
let x = tail(i) // x: [number] (inferred)

我相信在这种情况下您根本无法推断出元组类型。但是,这应该没问题,因为您不应该经常将文字传递给 tail