Skip to content

元祖类型

Tuple 类型是另一种 Array 类型,它确切地知道包含多少个元素,以及它在特定位置包含哪些类型。

typeScript
type StringNumberPair = [string, number];

这里, StringNumberPair 是一个 string 和 number 的元组类型。像 ReadonlyArray 一样,它在运行时没有表示,但对 TypeScript 来说是重要的。对于类型系统来说, StringNumberPair 描述了其索引 0 包含字符串和索引 1 包含数字的数组。

typeScript
function doSomething(pair: [string, number]) {
  const a = pair[0];
  const b = pair[1];
  // ...
}

doSomething(["hello", 42])

如果我们试图索引超过元素的数量,我们会得到一个错误:

typeScript
function doSomething(pair: [string, number]) {
  const c = pair[2];
}

我们还可以使用 JavaScript 的数组析构来对元组进行解构。

typescript
function doSomething(stringHash: [string, number]) {
  const [inputString, hash] = stringHash;

  console.log(inputString);

  console.log(hash);
}

除了这些长度检查,像这样的简单元组类型等同于 Array 的版本,它为特定的索引声明属性,并且用数字字面类型声明长度。

typescript
interface StringNumberPair {
  // 专有属性
  length: 2;
  0: string;
  1: number;

  // 其他 'Array<string | number>' 成员...
  slice(start?: number, end?: number): Array<string | number>;
}

另一件你可能感兴趣的事情是,元组可以通过在元素的类型后面写出问号(?)—— 可选的元组,元素只能出现在末尾,而且还影响到长度的类型。

typescript
type Either2dOr3d = [number, number, number?];

function setCoordinate(coord: Either2dOr3d) {
  const [x, y, z] = coord;
  console.log(`提供的坐标有 ${coord.length} 个维度`);
}

图元也可以有其余元素,这些元素必须是 array / tuple 类型。

typescript
type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];
  • StringNumberBooleans 描述了一个元组,其前两个元素分别是字符串和数字,但后面可以有任意数量的布尔。

  • StringBooleansNumber 描述了一个元组,其第一个元素是字符串,然后是任意数量的布尔运算,最后是一个数字。

  • BooleansStringNumber 描述了一个元组,其起始元素是任意数量的布尔运算,最后是一个字符串,然后是一个数字。

一个有其余元素的元组没有集合的 "长度"——它只有一组不同位置的知名元素。

typescript
const a: StringNumberBooleans = ["hello", 1];
const b: StringNumberBooleans = ["beautiful", 2, true];
const c: StringNumberBooleans = ["world", 3, true, false, true, false, true];

为什么可选元素和其余元素可能是有用的?它允许 TypeScript 将 tuples 与参数列表相对应。

typescript
function readButtonInput(...args: [string, number, ...boolean[]]) {
  const [name, version, ...input] = args;
  // ...
}

基本上等同于:

typescript
function readButtonInput(name: string, version: number, ...input: boolean[]) {
  // ...
}

当你想用一个其余 (rest) 参数接受可变数量的参数,并且你需要一个最小的元素数量,但你不想引入中间变量时,这很方便。