打字稿:我可以定义一个长度为 n 的元组类型吗? [英] Typescript: Can I define an n-length tuple type?
问题描述
我正在使用 Typescript 创建一个将棋游戏板.一个棋盘有 9 个等级和文件.
I am creating a shogi game board using Typescript. A shogi board has 9 ranks and files.
我想将 9x9 多维数组断言为一种类型,以确保数组的大小和内容.
I'd like to assert a 9x9 multidimensional array as a type to ensure both the size and contents of the array.
目前我正在以这种方式创建我的 9x9 板类型:
Currently I am creating my 9x9 board type this way:
type Board9x9<P> = [
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P],
[P, P, P, P, P, P, P, P, P]
];
interface IShogiBoardInternalState {
board: Board9x9<IShogiPiece>;
playerName: string;
isYourTurn: boolean;
}
问题:是否有一种更简单、更通用的方法来定义我称之为 Board9x9
的这个元组类型?
Question: Is there a less tedious, more generic way to define this tuple type which I have called Board9x9<P>
?
推荐答案
更新:
使用 递归条件类型(在 TypeScript 4.1.0 中添加),可以:
With Recursive conditional types (added in TypeScript 4.1.0) it is possible to:
type Tuple<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 Tuple9<T> = Tuple<T, 9>;
type Board9x9<P> = Tuple9<Tuple9<P>>;
原始答案:
Typescript 3 引入了 元组类型中的其余元素
Typescript 3 introduces rest elements in tuple types
元组类型的最后一个元素可以是 ...X 形式的剩余元素,其中 X 是数组类型
The last element of a tuple type can be a rest element of the form ...X, where X is an array type
为了限制元组的长度,我们可以使用与 { length: N }
To restrict the length of a tuple we can use intersection with { length: N }
type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & { length: TLength };
type Tuple9<T> = Tuple<T, 9>;
type Board9x9<P> = Tuple9<Tuple9<P>>;
这在 Tuple
类型的变量被初始化时起作用:
This works when variable of Tuple
type is being initialized:
const t: Tuple<number, 1> = [1, 1] // error: 'length' incompatible.
这里有一个警告,如果您尝试访问元组范围之外的索引处的非元素,typescript 不会警告您:
A caveat here, typescript won't warn you if you'll try to access non element at index out of tuple range:
declare const customTuple: Tuple<number, 1>;
customTuple[10] // no error here unfortunately
declare const builtinTuple: [number];
builtinTuple[10] // error: has no element at index '10'
有一个建议来添加指定元组类型长度的通用方法.
There's a suggestion to add a generic way to specify length of a tuple type.
这篇关于打字稿:我可以定义一个长度为 n 的元组类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!