讲解

数组是最常用的复合类型,有两种等价写法:number[](元素类型加方括号)和 Array(泛型写法)。短类型用第一种更常见;元素类型复杂时第二种可读性更好。标注数组的关键在于元素类型——TypeScript 会保证每次 push、每次读取都符合元素类型,越界读取本身不报错(JS 语义),但 strict 家族里的 noUncheckedIndexedAccess 可以让下标访问自动带上 undefined,后面严格模式章节会展开。

元组(tuple)是长度和每个位置类型都固定的特殊数组,写法是 [string, number] 这样的位置类型列表。它适合表达「结构固定的短序列」:坐标 [x, y]、键值对、CSV 的一行。函数返回多个值时返回元组比返回对象更轻量,配合解构使用非常顺手。元组可以带可选元素和剩余元素([string, ...number[]]),但日常用到的大多是两三个位置的简单形态。

还要注意只读数组 readonly number[]:它禁止 push、pop、直接改下标等一切修改操作,常用于函数参数——声明「我只读这个数组,不会动它」,既是文档也是编译器强制的承诺。ReadonlyArray 是它的泛型写法。

示例

数组的类型标注与常见操作:

const scores: number[] = [88, 92, 79];
scores.push(95);
// scores.push("满分"); // 若取消注释:string 不能赋给 number

const names: Array<string> = ["小林", "小陈"];
const total: number = scores.reduce((acc, cur) => acc + cur, 0);
console.log(`${names[0]} 的平均分:${total / scores.length}`);

元组表达固定结构,配合解构:

type Point = [number, number];

function distance(a: Point, b: Point): number {
  const [x1, y1] = a;
  const [x2, y2] = b;
  return Math.hypot(x1 - x2, y1 - y2);
}

const base: Point = [0, 0];
const target: Point = [3, 4];
console.log(`距离:${distance(base, target)}`);

函数返回元组 + 只读数组参数:

function minMax(values: readonly number[]): [number, number] {
  return [Math.min(...values), Math.max(...values)];
}

const data: number[] = [5, 3, 9, 1];
const [min, max] = minMax(data);
console.log(`最小 ${min},最大 ${max}`);

常见坑

  • 混类型数组写出 any[] 的效果:[1, "a"] 会被推断为 (number | string)[],通常是写错了;真想混合就显式写联合类型,让意图清晰。
  • 把元组当数组 push:元组允许 push 元素类型内的值(历史遗留设计),这会破坏长度约定——定义了 [string, number] 就不要再 push。
  • 下标访问不判空:arr[100] 编译不报错,运行时是 undefined。开启 noUncheckedIndexedAccess 或养成先判长度/用 .at() 的习惯。
  • sort() 原地修改:数组方法里 sort、reverse、splice 会改原数组,readonly 数组直接禁止调用它们;需要副本时用 toSorted() 等新方法。

小结

数组标注元素类型(T[] 或 Array);元组固定长度与各位置类型,适合结构化短序列;readonly 数组表达「只读不写」的承诺。下一章看对象类型与类型别名。