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); // 不报错
相关推荐
起名时在学Aiifox1 小时前
前端文件下载功能深度解析:从基础实现到企业级方案
前端·vue.js·typescript
满天星辰5 小时前
Typescript之类型总结大全
前端·typescript
前端小L11 小时前
专题一:搭建测试驱动环境 (TypeScript + Vitest)
前端·javascript·typescript·源码·vue3
Irene199111 小时前
TypeScript 中,void 是一种表示“无返回值”的类型
typescript·void
再希13 小时前
TypeScript初体验(四)在React中使用TS
javascript·react.js·typescript
EndingCoder13 小时前
函数基础:参数和返回类型
linux·前端·ubuntu·typescript
EndingCoder14 小时前
箭头函数和 this 绑定
linux·前端·javascript·typescript
小二·1 天前
微前端架构完全指南:qiankun 与 Module Federation 双方案深度对比(Vue 3 + TypeScript)
前端·架构·typescript
EndingCoder1 天前
枚举类型:常量集合的优雅管理
前端·javascript·typescript
起名时在学Aiifox1 天前
从零实现前端数据格式化工具:以船员经验数据展示为例
前端·vue.js·typescript·es6