Typescript数组与元组类型

JavaScript 数组在 Typescript中有数组与元组两种数据类型表示。

数组

相同类型的元素组成数组,数组长度不固定。

类型声明

  1. 单一类型,在类型后加上中括号[]
ini 复制代码
let arr: number[] = [1, 2, 3];
  1. 联合类型,用小括号将联合类型括起来并在联合类型后加中括号[]
typescript 复制代码
let arr: (number | string) = [1, 2, 3, 'hello'];
  1. 使用泛型,对于复杂的联合类型,使用泛型可读性更强
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'); // 类型不更新,报错

数组操作

  1. 编辑数组元素

对于有类型声明的数组,编辑数组元素,若类型不匹配编译时会报错;

ini 复制代码
let arr: number[] = [1, 2, 3];
arr.push('hello'); // 类型不匹配,报错
  1. 访问数组元素

数组长度不固定,因此访问数组元素时不会有出界错误。

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 特有的类型,元组元素的类型可以不同,每个元素都要声明类型。

类型声明

  1. 固定长度的元组,每个元素都要声明类型。
typescript 复制代码
let tuple: [number, string, boolean] = [1, 'hello', true];
  1. 元素可选的元组,在可选元素的类型声明后加上 "?"表示可选,可选元素要在必需元素后面。这种情况下元组长度同样可以认为是"固定的",比如下面这个例子中,元组的长度值就是 2 | 3,与不可能的长度值比较时会报错("==" 与 "===" 会,大小比较不会)。
arduino 复制代码
let tuple: [number, string, boolean?] = [1, 'hello'];
if(tuple.length === 4){ // 报错,长度不可能为4
}
if(tuple.length === 1){ // 报错,长度不可能为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); // 不报错
相关推荐
Wect3 小时前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
Dilettante2583 小时前
这一招让 Node 后端服务启动速度提升 75%!
typescript·node.js
jonjia20 小时前
模块、脚本与声明文件
typescript
jonjia20 小时前
配置 TypeScript
typescript
jonjia20 小时前
TypeScript 工具函数开发
typescript
jonjia20 小时前
注解与断言
typescript
jonjia20 小时前
IDE 超能力
typescript
jonjia20 小时前
对象类型
typescript
jonjia20 小时前
快速搭建 TypeScript 开发环境
typescript
jonjia20 小时前
TypeScript 的奇怪之处
typescript