TypeScript入门到精通——TypeScript类型系统基础——元组类型
TypeScript类型系统基础——元组类型
元组(Tuple)表示由有限元素构成的有序列表。在 JavaScript 中,没有提供原生的元组数据类型。TypeScript 对此进行了补充,提供了元组数据类型。由于元组数组之间存在很多共性,因此 TypeScript 使用数组来表示元组。
在 TypeScript 中,元组类型是数组类型的子类型。元组是长度固定的数组,并且元组中每个元素都有确定的类型。
一、元组的定义
定义元组类型的语法与定义数组字面量的语法相似,具体语法如下所示:
[T0, T1, T2, ..., Tn]
该语法中的 T0、T1 和 Tn 表示元组中元素的类型,针对元组中每一个位置上的元素都需要定义其数据类型。
不同于 TypeScript 数组元素类型,TypeScript 元组中每个元素类型不必相同。
例如,可以一个表示成绩的元组,元组的第一个元素是 string 类型的科目名,第二个元素是 number 类型的分数。示例如下:
let grades: [string, number][] = [["Math", 90], ["English", 85], ["Science", 95]];
若数组元素的类型与元组类型的定义不匹配时候,则会产生编译错误。示例如下:
let grades: [string, number][] = [["Math", "90"], ["English", 85], ["Science", 95]];
报错信息如下:
Type 'string' is not assignable to type 'number'.
二、只读元组
元组可以定义为只读元组,这与只读数组是类似的。只读元组类型是只读数组类型的子类型。
定义只读元组有以下两种方式:
1、使用 readonly 修饰符。
2、使用 "Readonly<T>"工具类型。
2.1、readonly
Typescript 3.4 版本中引入了一种新语法,使用 readonly 修饰符能够定义只读元组。在定义只读元组时,将 readonly 修饰符置于元组类型之前即可。示例如下:
const point: readonly [number, number] = [10, 10];
此例中,point 是包含两个元素的只读元组。
2.2、Readonly<T>
由于 TypeScript 3.4 支持了使用 readonly 修饰符来定义只读元组,所以从 TypeScript 3.4 开始可以使用 "Readonly<T>" 工具类型来定义只读元组。、
const point: Readonly<[number, number]> = [10, 10];
三、访问元组中的元素
由于元组在本质上是数组,所以我们可以使用访问数组元素的方法去访问元组中的元素。
let person = ['John', 30]; // 这是一个元组 console.log(person[0]); // 这会打印出 'John'
这里,person[0]
返回一个新的元组,只包含'John'
这个元素。这和数组的行为是不同的,数组的索引访问会直接返回该索引对应的元素,而不是一个新的数组。
元组可以像数组一样被遍历,示例如下:
let person = ['John', 30]; for (let i = 0; i < person.length; i++) { console.log(person[i]); // 这会打印出 'John' 和 30 }
四、元组类型中的剩余元素
在定义元组类型时,可以将最后一个元素定义为剩余元素。定义元组剩余元素类型的语法如下所示:
[...T[]]
该语法中,元组的剩余元素是数组类型,T 表示剩余元素的类型。
const tuple: [number, ...string[]] = [0, 'a', 'b'];
五、元组类型与数组类型的兼容性
元组类型是数组类型的子类型,只读元组类型是只读数组类型的子类型。在进行赋值操作时,允许将元组类型赋值给类型兼容的元组类型和数组类型。
const point: [number, number] = [0, 0] const nums: number[] = point; //正确 const strs: string[] = point; //错误
元组类型允许赋值给常规数组类型和只读数组类型,但只读元组类型只允许赋值给只读数组类型。
const tuple: [number, string] = [0, 'hello']; // 正确
const readOnlyTuple: readonly [number, string] = [0, 'hello']; // 正确
const array: number[] = [0, 1, 2]; // 正确
const readOnlyArray: readonly number[] = [0, 1, 2]; // 正确
readOnlyTuple = [1, 'world']; // 错误:只读属性不能赋值
readOnlyArray = [1, 'world']; // 错误:只读属性不能赋值