在 TypeScript 中检测固定长度元组类型与数组类型

szy*_*ski 1 typescript typescript-generics typescript-typings

我有一个通用函数,我想让它只接受固定长度(可能是混合类型)元组作为类型参数。我事先不知道可能的元组类型 - 它应该接受任何固定长度的元组。

doSomething<[number, string, boolean]>(); // this should be okay
doSomething<number[]>(); // this should throw a compiler error
Run Code Online (Sandbox Code Playgroud)

我知道我可以将长度限制为特定的数字文字(为简洁起见,省略数组检查):

type LengthOf<N extends number> = {
  length: N;
}
function doSomething<T extends LengthOf<2>(){};
doSomething<[any, any]>(); // ok
doSomething<[any]>(); // error
Run Code Online (Sandbox Code Playgroud)

但我不能使用此方法将长度限制为任何数字文字,因为任何数字文字都会扩展数字,这也是length可变长度数组的类型。

这在 TypeScript 中可能吗?

jca*_*alz 5

我不确定你为什么想要这个,但你可以加强通用约束,以便它只接受length属性比以下更窄的数组类型number

function doSomething<
    T extends (number extends T['length'] ? [] : any[])
>() { };
Run Code Online (Sandbox Code Playgroud)

这将允许固定长度的元组或长度是数字文字的联合的元组,例如具有可选元素的元组

doSomething<[number, string, boolean]>(); // okay
doSomething<[number, string, boolean?]>(); // okay
Run Code Online (Sandbox Code Playgroud)

同时不允许数组或开放式元组(带有剩余元素):

doSomething<number[]>(); // error
doSomething<[number, string, ...boolean[]]>(); // error
Run Code Online (Sandbox Code Playgroud)

Playground 代码链接