今天进入进阶篇的学习和总结,先来说一下类型别名、字符串字面量类型和元祖。
类型别名
类型别名用来给一个类型起个新名字
1 | type Name = string; |
我们使用 type
创建类型别名,常用于联合类型。
字符串字面量类型
字符串字面量类型用来约束取值只能是某几个字符串中的一个。1
2
3
4
5
6type EventNames = 'click' | 'scroll' | 'mouseover';
function handleEvent(ele: Element, event: EventNames){
//do something;
}
handleEvent(document.getElementById('hello'), 'scroll'); //编译成功
handleEvent(document.getElementById('world'), 'dbclick'); //编译错误
上面我们使用type
定义了一个字符串字面量类型EventNames
,它只能取三种字符串中的一种。
注意:类型别名和字符串子面量类型都是使用type进行定义
。
元组(Tuple)
数组合并了相同类型的对象,而元组合并了不同类型的对象。元组起源于函数编程语言(如 F#),在这些语言中频繁使用元组。
简单的例子
定义一对值分别为string
和number
的元祖:1
let tom:[string, number] = ['tom', 20];
当赋值或访问一个已知索引的元素时,会得到正确的类型:1
2
3
4
5
6let tom:[string, number];
tom[0] = 'tom';
tom[1] = 20;
tom[0].slice(1);
tom[1].toFixed(2);
也可以只赋值其中一项:1
2let tom: [string, number];
tom[0] = 'tom';
但当直接对元祖类型的变量进行初始化或者赋值的时候,需要提供所有元祖类型中指定的项。1
2
3
4
5
6
7
8
9
10
11let tom: [string, number];
tom = ['tom', 20];
//编译成功
let tom: [string, number] = ['tom'];
//编译错误
let tom: [string, number];
tom = ['tom'];
tom[1] = 20;
//编译错误
越界的元素
当赋值给越界的元素时,它的类型会被限制为元祖中每个类型的联合类型:1
2let tom: [string, number];
tom = ['tom', 20, 'male'];
上面的例子中,数组的第三项满足联合类型 string | number。1
2
3
4
5
6let tom: [string, number];
tom = ['tom', 20];
tom.push('male');
tom.push(true);
// index.ts(4,14): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string | number'.
// Type 'boolean' is not assignable to type 'number'.
当访问一个越界的元素,也会识别为元组中每个类型的联合类型:1
2
3
4
5let tom: [string, number];
tom = ['tom', 20, 'male'];
console.log(tom[2].slice(1));
// index.ts(4,24): error TS2339: Property 'slice' does not exist on type 'string | number'.
之前提到过,如果一个值是联合类型,我们只能访问此联合类型的所有类型里共有的属性或方法
。