固定长度的元组

9

Typescript中的元组允许添加任何之前使用过的类型的额外元素,但我想限制长度。我尝试了 & { length: 2 }但它没有起作用

declare var a: [string, number] & { length: 2 };

a[0] = "1"
a[1] = 2;
a[2] = "3";
a[3] = 4;

[2][3]的赋值没有出错。我该如何指定相应的类型?


这里有一些解决方案:https://dev59.com/WlgR5IYBdhLWcg3wlOIr#59906630 - colxi
@colxi,实际上从3.1版本开始就没有这样的问题了。 - Qwertiy
元组不会阻止您在数组初始化后添加/删除键,但有解决方案可以实现安全的FixedLengthArray类型签名。 - colxi
@colxi,是的,我已经理解了你对那个问题的回答。 - Qwertiy
3个回答

8

使用类型 never 用于数组尾部:

declare var a: [string, number, ...never[]];

您将会得到:

类型'"3"'不能赋值给类型'never'。

类型'4'不能赋值给类型'never'。


3

如果您正在使用Typescript 4.1或更高版本,您可以利用递归条件类型创建具有灵活长度的元组类型:

type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;

这使您可以轻松指定元组的值类型和长度

type T1 = TupleOf<string, 3>;

那么这样的元组将会编译

const tuple: T1 = ['one', 'two', 'three'];

然而这个不会

const tuple: T1 = ['one', 'two', 'three', 'four'];

TS2322: Source has 4 element(s) but target allows only 3

当然,缺点是您无法轻松地在元组中指定不同的类型,因此这种方法更适合单类型元组。


非常有用的回答,谢谢你。 - Bernard Borg

0

如果您正在使用Typescript 3.1或更新版本,则无需为元组添加特殊限制:

declare var a: [string, number];

你可能会注意到这段代码

declare var a: [string, number];

a[0] = "1"
a[1] = 2;
a[2] = "3";
a[3] = 4;

在3.0.1编译通过但是在3.1.6无法编译并显示以下错误信息

元组长度为2,下标 '2' 超出范围。
元组长度为2,下标 '3' 超出范围。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接