JavaScript 数组在 Typescript中有数组与元组两种数据类型表示。
数组
相同类型的元素组成数组,数组长度不固定。
类型声明
- 单一类型,在类型后加上中括号[]
ini
let arr: number[] = [1, 2, 3];
- 联合类型,用小括号将联合类型括起来并在联合类型后加中括号[]
typescript
let arr: (number | string) = [1, 2, 3, 'hello'];
- 使用泛型,对于复杂的联合类型,使用泛型可读性更强
typescript
let arr: Array<number> = [1, 2, 3];
let arr1: Array<number | string> = [1, 2, 3, 'hello'];
类型推断
对于没有类型声明的空数组,类型推断会将数组类型推断为 any[],随着数组元素的添加,数组类型会随之更新;
对于没有类型声明,但是有初始值的数组,类型推断会推断数组初始类型,后续添加数组元素,数组类型不会更新,从而类型报错;
scss
let arr1 = []; // 类型推断为 any[]
arr1.push(1); // 类型推断更新为 number[]
arr1.push('hello'); // 类型推断更新为 (number | string)[]
let arr2 = [1]; // 没有类型声明,类型推断为 number[]
arr2.push('hello'); // 类型不更新,报错
数组操作
- 编辑数组元素
对于有类型声明的数组,编辑数组元素,若类型不匹配编译时会报错;
ini
let arr: number[] = [1, 2, 3];
arr.push('hello'); // 类型不匹配,报错
- 访问数组元素
数组长度不固定,因此访问数组元素时不会有出界错误。
ini
let arr: number[] = [1, 2, 3];
let x = arr[3]; // 不会出界警告
只读数组
可以在声明类型时在类型前加上 readonly 来声明只读数组,也可以使用泛型提供的Readonly 和 ReadonlyArray 声明只读数组,Readonly泛型声明数组元素类型需要加中括号 []。
使用常量断言 as const 也可以声明只读数组。
对只读数组进行增、删、改操作都会报错。
ini
const arr: readonly number[] = [1, 2, 3];
const arr: Readonly<number[]> = [1, 2, 3];
const arr: ReadonlyArray<number> = [1, 2, 3];
const arr = [1, 2, 3] as const;
arr.push(4); // 报错
arr.pop(); // 报错
arr[0] = 4; //报错
元组
元组是 Typescript 特有的类型,元组元素的类型可以不同,每个元素都要声明类型。
类型声明
- 固定长度的元组,每个元素都要声明类型。
typescript
let tuple: [number, string, boolean] = [1, 'hello', true];
- 元素可选的元组,在可选元素的类型声明后加上 "?"表示可选,可选元素要在必需元素后面。这种情况下元组长度同样可以认为是"固定的",比如下面这个例子中,元组的长度值就是 2 | 3,与不可能的长度值比较时会报错("==" 与 "===" 会,大小比较不会)。
arduino
let tuple: [number, string, boolean?] = [1, 'hello'];
if(tuple.length === 4){ // 报错,长度不可能为4
}
if(tuple.length === 1){ // 报错,长度不可能为1
}
- 长度不确定的元组,使用扩展运算符 "..." 可以声明长度不固定的元组,扩展运算符可以用在元组的任何位置。
typescript
let tuple: [number, string, ...number[]];
let tuple1: [number, ...number[], string];
let tuple2: [...number[], string, number];
类型推断
使用元组时,必须明确给出类型声明,否则 Typescript会将其推断为数组。
ini
let tuple = [1, 'hello']; // tsc将其推断为 (number | string)[]类型的数组
数组操作
由于每个元组元素都需要声明类型,因此元组的长度在声明时就已经确定(扩展运算符声明的除外),后续操作不能改变数组长度,否则报错,访问元组元素也不能出界。
typescript
let tuple: [number, string, boolean] = [1, 'hello', true];
let x = tuple[3]; // 报错
只读元组
可以在声明类型时在类型前加上 readonly 来声明只读元组,也可以使用泛型提供的Readonly声明只读元组;
用常量断言 as const 也可以声明只读元组。
typescript
const tuple: readonly [number, string, boolean] = [1, 'hello', true];
const tuple: Readonly<[number, string, boolean]> = [1, 'hello', true];
const tuple = [1, 'hello', true] as const;
扩展运算符传参
使用扩展运算符传递函数参数时,数组的长度会被 tsc 认为不固定从而可能报错,要使用长度固定的元组再用扩展运算符传参。
typescript
let arr: number[] = [1, 2];
let tuple: [number, number] = [1, 2];
function add(x: number, y: number){
return x+y;
}
add(...arr); // 报错
add(...tuple); // 不报错