打字稿:我可以定义一个长度为 n 的元组类型吗? [英] Typescript: Can I define an n-length tuple type?

查看:25
本文介绍了打字稿:我可以定义一个长度为 n 的元组类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆