# 对象类型-数组和元祖

本章讲解如何定义一个基础的数组类型和有限元素的数组类型元祖。

# 数组

采用 类型[] 的方式申明特定类型的数组。

// 定义 number 类型数组
let numArr: number[] = [1, 2, 3];

// 合法
numArr.push(12);
// 报错推入数据非 number 类型
numArr.push('demo');

// 定义字符串类型数组
let strArr: string[] = ['foo', 'bar'];
// 合法
strArr[3] = 'foobar';

// 报错, 不能将 number 类型赋值给 string
strArr[0] = 21;

你也可以使用 Array<类型> 替代 类型[] 的表示, 该语法会在后续 泛型章节 涉及。 <<< ./examples/types/array/Array.ts

# 只读数组

可以采用属性修复符 readonly 限制数组为只读。

type ReadOnlyArr = readonly string[];

let readStrArr: ReadOnlyArr = ['foo', 'bar'];

// 合法
console.log(readStrArr[0]);

// 报错, 数组只读无法修改
readStrArr[0] = 'bar';

// 报错, 只读数组无法添加新数据
readStrArr.push('bar');
readStrArr[3] = 'bar';

也可采用 ReadonlyArray<类型> 限制只读。

// 效果同 let arr2:readonly number[] = [1,2,3]
let arr2: ReadonlyArray<number> = [1, 2, 3];

// 合法
console.log(readStrArr[0]);

// 报错, 数组只读无法修改
readStrArr[0] = 'bar';

// 报错, 只读数组无法添加新数据
readStrArr.push('bar');
readStrArr[3] = 'bar';

# 元祖(tuple)

元祖是长度固定的数组,采用 [类型1,类型2,...] 申明元祖。

// 申明长度为 2 第一个元素为数值,第二个元素为字符串的元祖
let tuple1: [number, string];
// 合法
tuple1 = [1, 'foo'];

//报错,第一个值必须为 nuber 类型
tuple1[0] = 'bar';
// 报错, 元祖长度固定不能扩充
tuple1[3] = 12;

//TODO:  合法, TypeScript 不检测动态注入值
tuple1.push(12);

# 元素元素的动态增加

虽然元祖类型是为了申明固定长度的数组。你任可采用 push,shift 等 api 动态修改数组。新增加的元素必须是元祖中定义所有类型之一。

// 申明长度为 2 第一个元素为数值,第二个元素为字符串的元祖
let x1: [number, string];
// 合法
x1 = [1, 'foo'];

//报错, 不能采用此方式增加数据
x1[3] = 12;

// 合法
x1.push(1);

// 合法
x1.push('demo');

// 报错,插入元素不是 number  或 string 类型
x1.push(false);

// 合法, 在数组开始插入元素 `demo` ,虽然和元祖类型不匹配但 TypeScript 无法识别
x1.unshift('demo');

// 合法, 替换索引为 1 位置的元素为 10,虽然此处该为 string 类型,但 TypeScript 无法检测
x1.splice(1, 1, 10);

console.log(x1); // 返回 [ 'demo', 10, 'foo', 1, 'demo' ]

# 只读元祖

由于元祖也是数组,也支持采用 readonly 修饰符。

type ReadOnlyTuple = readonly [number, string];

let tuple2: ReadOnlyTuple = [1, 'foo'];

// 合法
tuple2 = [1, 'foo'];

//报错,元祖元素不能修改
tuple2[0] = 1;

// 报错, 元祖元素不能动态扩充
// 注意未申明 readonly 元祖虽然长度固定但仍可动态扩充
tuple2.push(12);

# 元祖可选元素

元祖同样支持采用 ? 表示可选元素。

let t1: [number, string?, boolean?];
t1 = [42, 'hello', true];
t1 = [42, 'hello'];
t1 = [42];

注意,可选元素之后必须都为可选!

# 总结

本章知识点如下:

  1. 采用 类型[] 语法限制特定类型的数组元素
  2. 采用 元祖(tuple) [类型1,类型2] 限制固定长度的数组
    1. 动态添加的元祖元素属于定义类型中的一种