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); // 不报错
相关推荐
SuniaWang3 小时前
《Spring AI + 大模型全栈实战》学习手册系列· 专题二:《Milvus 向量数据库:从零开始搭建 RAG 系统的核心组件》
java·人工智能·分布式·后端·spring·架构·typescript
console.log('npc')3 小时前
partial在react接口定义中是什么意思
前端·javascript·typescript
码路飞5 小时前
Electron 太胖了?试试 Electrobun,12MB 打包一个 AI 桌面助手
typescript·electron
小鲤鱼ya5 小时前
vue3 + ts + uni-app 移动端封装图片上传添加水印
前端·typescript·uni-app·vue3
zhangjikuan895 小时前
在 ArkTS 中,Promise 的使用比 TypeScript 更严格(必须显式指定泛型类型)
前端·javascript·typescript
向上的车轮5 小时前
TypeORM——基于 TypeScript/JavaScript 的对象关系映射(ORM)框架
javascript·typescript·typeorm
Yan-英杰6 小时前
TypeScript+React 全栈生态实战:从架构选型到工程落地,告别开发踩坑
javascript·学习·typescript
牧码岛7 小时前
服务端之NestJS请求解析体系、从HTTP报文到参数注入的工程化实践、控制器方法、装饰器、Headers、Query、Param、Body、Req
typescript·nestjs
We་ct20 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
紫_龙1 天前
最新版vue3+TypeScript开发入门到实战教程之DOM操作
javascript·vue.js·typescript