TypeScript 元组

TypeScript 中的元组(Tuple)详解

元组(Tuple) 是 TypeScript 对数组的增强类型,它允许你定义一个元素数量固定每个元素类型可能不同的数组。普通数组(如 number[])要求所有元素类型相同,且长度不固定,而元组正好解决了“固定结构”的需求。

1. 基本声明与使用

// 声明一个包含 string 和 number 的元组
let person: [string, number] = ["Alice", 30];

// 访问元素(类型安全)
let name: string = person[0];   // "Alice"
let age: number = person[1];    // 30

// person[2] = "extra";         // 错误:索引越界,TS 会报错
// person = ["Bob", "25"];      // 错误:第二个元素必须是 number
// person = ["Charlie"];        // 错误:长度不足,必须正好 2 个元素

2. 类型推断

大多数情况下可以省略显式类型注解,TS 会自动推断:

let tuple = ["Bob", 25, true];  
// 类型被推断为 [string, number, boolean]

// 一旦推断后,类型和长度固定
tuple[1] = "twenty";            // 错误:必须是 number
tuple.push("extra");            // 注意:push 不会报错!(TS 局限性,见下文)

3. 可选元素(TS 4.0+)

元组的后续元素可以标记为可选(必须放在末尾):

let optionalTuple: [string, number?] = ["Charlie"];     // OK,只有一个元素
optionalTuple = ["Dave", 28];                           // OK,有两个元素

// optionalTuple = ["Eve", 30, true];                  // 错误:超出可选范围

4. 剩余元素(Rest Elements,TS 4.2+)—— 可变长度元组

使用展开运算符允许末尾元素为数组(不定长度):

// 前两个固定,后续为任意数量的 number
let scores: [string, number, ...number[]] = ["Math", 95];
scores = ["English", 88, 92, 85];  // OK

// 访问
let subject: string = scores[0];
let baseScore: number = scores[1];
let extraScores: number[] = scores.slice(2);

5. 只读元组

防止元组被修改:

let readonlyTuple: readonly [string, number] = ["Fixed", 100];

// readonlyTuple[0] = "Change";  // 错误:只读
// readonlyTuple.push(200);     // 错误:没有 push 方法

6. 常见应用场景

元组非常适合表示固定结构的数据

// 1. 坐标点
type Point = [number, number];
let origin: Point = [0, 0];

// 2. RGB 颜色
type Color = [number, number, number];
let red: Color = [255, 0, 0];

// 3. HTTP 响应
type HttpResponse = [number, string];  // [statusCode, body]
let success: HttpResponse = [200, "OK"];
let notFound: HttpResponse = [404, "Not Found"];

// 4. 函数返回多个值
function getUserInfo(): [string, number, boolean] {
  return ["Alice", 30, true];
}

let [username, userAge, isAdmin] = getUserInfo();  // 解构赋值

7. 注意事项与局限性

  • push/pop 等方法不会被类型检查限制
  let tuple: [string, number] = ["A", 1];
  tuple.push(2);  // 不会报错!运行时长度变为 3

解决方案:使用 as constreadonly 防止修改:

  let safeTuple = ["A", 1] as const;  // 类型为 readonly ["A", 1]
  // safeTuple.push(2);               // 错误
  • 标签元组(Labeled Tuples,TS 4.0+) —— 提高可读性(仅用于文档,不影响类型):
  type Person = [name: string, age: number, isActive: boolean];
  let p: Person = ["Bob", 25, true];  // 标签提示更清晰

8. 元组 vs 普通数组 vs 对象

类型长度元素类型推荐场景
number[]可变统一同类型元素列表(如成绩列表)
[string, number]固定可不同固定结构数据(如坐标、键值对)
{ name: string; age: number }可不同复杂对象,属性多且有意义名称

何时选元组:当你需要一个小型、固定顺序的异构集合,且不需要属性名时。

小结:元组类型速查

写法含义示例
[string, number]固定 2 元素["Alice", 30]
[number, number?]第二个可选["x", 10]["x"]
[string, ...number[]]第一个固定,后续任意数量 number["scores", 90, 85]
readonly [string, boolean]只读元组["status", true] as const
as const将数组字面量转为只读元组let t = [1, "hi"] as const;

如果您想看更多实际示例(如解构元组、元组在函数参数中的使用、与接口的结合),或者想了解元组与联合类型的高级玩法,请告诉我!

文章已创建 3383

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部