TypeScript数组与元组 #

一、数组类型 #

1.1 数组类型定义方式 #

TypeScript提供了两种定义数组类型的方式:

方式一:元素类型后加[] #

typescript
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: string[] = ['a', 'b', 'c'];
let booleans: boolean[] = [true, false, true];

方式二:使用泛型Array #

typescript
let numbers: Array<number> = [1, 2, 3, 4, 5];
let strings: Array<string> = ['a', 'b', 'c'];
let booleans: Array<boolean> = [true, false, true];

1.3 数组初始化 #

typescript
let empty: number[] = [];
let initialized: string[] = new Array(3);
let fromValues: number[] = Array.of(1, 2, 3);
let fromArrayLike: number[] = Array.from({ length: 3 }, (_, i) => i + 1);

二、数组操作 #

2.1 添加和删除元素 #

typescript
let arr: number[] = [1, 2, 3];

arr.push(4);
arr.pop();

arr.unshift(0);
arr.shift();

arr.splice(1, 1, 10, 20);

2.2 访问元素 #

typescript
let arr: string[] = ['a', 'b', 'c', 'd', 'e'];

console.log(arr[0]);
console.log(arr[arr.length - 1]);
console.log(arr.at(-1));

2.3 遍历数组 #

typescript
let arr: number[] = [1, 2, 3, 4, 5];

for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

for (const item of arr) {
    console.log(item);
}

arr.forEach((item, index) => {
    console.log(`${index}: ${item}`);
});

2.4 数组方法 #

typescript
let arr: number[] = [1, 2, 3, 4, 5];

let doubled: number[] = arr.map(x => x * 2);

let evens: number[] = arr.filter(x => x % 2 === 0);

let sum: number = arr.reduce((acc, x) => acc + x, 0);

let found: number | undefined = arr.find(x => x > 3);

let index: number = arr.findIndex(x => x > 3);

let hasEven: boolean = arr.some(x => x % 2 === 0);

let allPositive: boolean = arr.every(x => x > 0);

let sorted: number[] = [...arr].sort((a, b) => b - a);

let reversed: number[] = [...arr].reverse();

let sliced: number[] = arr.slice(1, 3);

let joined: string = arr.join('-');

let includes: boolean = arr.includes(3);

三、只读数组 #

3.1 使用readonly修饰符 #

typescript
let arr: readonly number[] = [1, 2, 3];

arr.push(4);
arr[0] = 10;

3.2 使用ReadonlyArray #

typescript
let arr: ReadonlyArray<number> = [1, 2, 3];

arr.push(4);

3.3 只读数组的特点 #

typescript
let readonly: readonly number[] = [1, 2, 3];
let normal: number[] = readonly;

let normal: number[] = readonly as number[];

3.4 函数参数中使用只读数组 #

typescript
function sum(arr: readonly number[]): number {
    return arr.reduce((acc, x) => acc + x, 0);
}

const numbers = [1, 2, 3, 4, 5];
console.log(sum(numbers));

四、多维数组 #

4.1 二维数组 #

typescript
let matrix: number[][] = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

console.log(matrix[0][0]);
console.log(matrix[1][2]);

4.2 创建二维数组 #

typescript
let rows = 3;
let cols = 4;
let grid: number[][] = Array.from({ length: rows }, () => Array(cols).fill(0));

let identity: number[][] = Array.from({ length: 3 }, (_, i) => 
    Array.from({ length: 3 }, (_, j) => (i === j ? 1 : 0))
);

4.3 遍历二维数组 #

typescript
let matrix: number[][] = [
    [1, 2, 3],
    [4, 5, 6]
];

for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
        console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
    }
}

matrix.forEach((row, i) => {
    row.forEach((cell, j) => {
        console.log(`matrix[${i}][${j}] = ${cell}`);
    });
});

4.4 三维数组 #

typescript
let cube: number[][][] = [
    [[1, 2], [3, 4]],
    [[5, 6], [7, 8]]
];

console.log(cube[0][1][0]);

五、元组类型 #

5.1 基本元组 #

元组是一个固定长度和类型的数组。

typescript
let tuple: [string, number] = ['hello', 10];

let name: string = tuple[0];
let age: number = tuple[1];

5.2 元组操作 #

typescript
let tuple: [string, number] = ['hello', 10];

tuple.push(20);
tuple.push('world');

console.log(tuple);
console.log(tuple[2]);

5.3 只读元组 #

typescript
let tuple: readonly [string, number] = ['hello', 10];

tuple.push(20);
tuple[0] = 'world';

5.4 可选元素 #

typescript
let tuple: [string, number?] = ['hello'];
tuple = ['hello', 10];

function getConfig(): [string, number?] {
    return ['default'];
}

5.5 剩余元素 #

typescript
let tuple: [string, ...number[]] = ['hello', 1, 2, 3, 4, 5];

let tuple2: [number, ...string[]] = [1, 'a', 'b', 'c'];

let tuple3: [...string[], number] = ['a', 'b', 'c', 1];

5.6 元组标签 #

typescript
let tuple: [name: string, age: number] = ['TypeScript', 12];

console.log(tuple[0]);
console.log(tuple[1]);

六、元组与数组的区别 #

6.1 类型对比 #

typescript
let arr: number[] = [1, 2, 3];
arr.push(4);
arr.push('hello');

let tuple: [number, string] = [1, 'hello'];
tuple.push(2);
tuple.push('world');

6.2 长度对比 #

typescript
let arr: number[] = [1, 2];
arr = [1, 2, 3, 4, 5];

let tuple: [number, string] = [1, 'hello'];
tuple = [1, 'hello', 'world'];

6.3 使用场景 #

typescript
let point: [number, number] = [10, 20];

let rgb: [number, number, number] = [255, 128, 0];

let entry: [string, number] = ['key', 100];

let result: [number, string] = [200, 'OK'];

七、数组类型推断 #

7.1 自动推断 #

typescript
let arr = [1, 2, 3];

let mixed = [1, 'two', true];

let nested = [[1, 2], [3, 4]];

7.2 as const断言 #

typescript
let arr = [1, 2, 3] as const;

arr.push(4);
arr[0] = 10;

let tuple = [1, 'two'] as const;

7.3 满足特定类型 #

typescript
let arr: number[] = [1, 2, 3] as const;

let arr: readonly number[] = [1, 2, 3] as const;

八、常见数组类型 #

8.1 联合类型数组 #

typescript
let mixed: (string | number)[] = [1, 'two', 3, 'four'];

let result: (string | number | boolean)[] = [1, 'hello', true];

8.2 对象数组 #

typescript
interface User {
    id: number;
    name: string;
}

let users: User[] = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
];

8.3 函数数组 #

typescript
let callbacks: (() => void)[] = [
    () => console.log('first'),
    () => console.log('second')
];

callbacks.forEach(cb => cb());

8.4 数组元组混合 #

typescript
let data: [string, ...number[]] = ['scores', 90, 85, 95];

let entries: [string, number][] = [
    ['a', 1],
    ['b', 2],
    ['c', 3]
];

九、数组解构 #

9.1 基本解构 #

typescript
let arr: number[] = [1, 2, 3];
let [a, b, c] = arr;

let [first, ...rest] = arr;

9.2 元组解构 #

typescript
let tuple: [string, number, boolean] = ['hello', 42, true];
let [str, num, bool] = tuple;

9.3 忽略元素 #

typescript
let arr: number[] = [1, 2, 3, 4, 5];
let [, second, , fourth] = arr;

9.4 默认值 #

typescript
let arr: (number | undefined)[] = [1, undefined, 3];
let [a = 0, b = 0, c = 0] = arr;

十、实战示例 #

10.1 分页数据 #

typescript
interface Page<T> {
    data: T[];
    total: number;
    page: number;
    pageSize: number;
}

interface User {
    id: number;
    name: string;
}

function getUsers(page: number, pageSize: number): Page<User> {
    const allUsers: User[] = [
        { id: 1, name: 'Alice' },
        { id: 2, name: 'Bob' },
        { id: 3, name: 'Charlie' }
    ];
    
    const start = (page - 1) * pageSize;
    const data = allUsers.slice(start, start + pageSize);
    
    return {
        data,
        total: allUsers.length,
        page,
        pageSize
    };
}

10.2 坐标系统 #

typescript
type Point2D = [number, number];
type Point3D = [number, number, number];

function distance2D(a: Point2D, b: Point2D): number {
    const [x1, y1] = a;
    const [x2, y2] = b;
    return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}

function distance3D(a: Point3D, b: Point3D): number {
    const [x1, y1, z1] = a;
    const [x2, y2, z2] = b;
    return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2);
}

10.3 键值对处理 #

typescript
type Entry<K, V> = [K, V];

function mapToEntries<K extends string | number | symbol, V>(
    map: Record<K, V>
): Entry<K, V>[] {
    return Object.entries(map) as Entry<K, V>[];
}

function entriesToMap<K extends string | number, V>(
    entries: Entry<K, V>[]
): Record<K, V> {
    return Object.fromEntries(entries) as Record<K, V>;
}

十一、总结 #

本章介绍了TypeScript的数组与元组类型:

数组要点 #

  1. 两种定义方式:type[]Array<type>
  2. 只读数组:readonly type[]ReadonlyArray<type>
  3. 多维数组:type[][]
  4. 丰富的数组方法

元组要点 #

  1. 固定长度和类型的数组
  2. 可选元素:[type1, type2?]
  3. 剩余元素:[type1, ...type2[]]
  4. 只读元组:readonly [type1, type2]

选择建议 #

  • 使用数组:长度可变的同类型集合
  • 使用元组:固定长度、已知类型的序列
  • 使用只读:不需要修改的集合
最后更新:2026-03-26