Skip to content

TypeScript 元组

元组(Tuple)是 TypeScript 中一个特殊的类型,它允许你表示一个已知元素数量和类型的数组。与普通数组不同,元组中每个位置上的元素类型是固定的。

声明和初始化元组

你可以通过在方括号 [] 中指定一系列类型来定义一个元组。

typescript
// 声明一个元组类型,它包含一个 string 和一个 number
let person: [string, number];

// 初始化
person = ["John Doe", 30]; // OK

// 顺序必须匹配
// person = [30, "John Doe"]; // Error: Type 'number' is not assignable to type 'string'.

// 数量必须匹配
// person = ["John Doe"]; // Error: Type '[string]' is not assignable to type '[string, number]'.

访问元组元素

你可以像访问数组元素一样,使用索引来访问元组中的元素。TypeScript 会根据索引提供正确的类型提示。

typescript
console.log(person[0]); // 类型是 string
console.log(person[1]); // 类型是 number

// 调用相应类型的方法
console.log(person[0].substring(0, 4)); // "John"
console.log(person[1].toFixed(2)); // "30.00"

// person[0] = 100; // Error: Type 'number' is not assignable to type 'string'.

元组的解构赋值

你可以使用解构赋值来方便地获取元组中的所有元素。

typescript
let [fullName, age] = person;

console.log(fullName); // "John Doe"
console.log(age);      // 30

可选的元组元素

元组元素也可以是可选的,通过在类型后添加 ? 来标记。可选元素必须在元组的末尾。

typescript
let car: [string, number, boolean?];

car = ["Toyota", 2022]; // OK
car = ["Honda", 2023, true]; // OK

元组与数组的比较

特性数组 (Array)元组 (Tuple)
长度可变的,不固定固定的,在定义时确定
类型所有元素通常是同一种类型 (string[])每个元素可以有不同的、预定义的类型 ([string, number])
用途用于存储同类数据的列表用于表示一组固定的、异构的数据,例如键值对、函数的多个返回值等
类型安全保证所有元素符合数组类型保证每个位置的元素符合其指定的类型

元组的越界访问

在 TypeScript 的早期版本中,对元组进行越界操作(例如 push 一个新元素)是允许的,但访问这个越界元素时,其类型会被视为元组中所有可能类型的联合类型。

typescript
let myTuple: [string, number] = ["hello", 10];

// 在 TypeScript 4.0 之前,这是允许的
// myTuple.push(true); 

// 访问越界元素
// let value = myTuple[2]; // value 的类型是 string | number

然而,随着 TypeScript 的发展,对元组的类型检查变得越来越严格。现在,通常不建议对元组进行 push 等改变其长度的操作,因为这违背了元组“固定长度”的初衷。

常见用例

  • 函数的多个返回值: 当一个函数需要返回多个不同类型的值时,元组是一个很好的选择。

    typescript
    function fetchUser(): [string, number] {
        // ... 逻辑
        return ["admin", 1];
    }
  • 表示键值对: 在处理像 Object.entries() 返回的数据时。

    typescript
    const entries: [string, any][] = Object.entries({ name: "Alice", age: 25 });
    // entries 是一个元组数组: [["name", "Alice"], ["age", 25]]

本站内容仅供学习和研究使用。