前言
在初步学习了 TypeScript 的变量声明后,对它的静态类型检查功能简直是爱不释手,但同时也发现一个问题:在正常的开发中,一个变量的类型有时可能不仅仅只限于 number 或者 string 中的一种,有可能是两种类型或者更多,比如:
代码语言:javascript复制// index.js
let res;
if(userInfo.age && userInfo.age > 12){
res = userInfo.age;
}else{
res = userInfo.name;
}
上面例子中的 res 类型可能是 number,也可能是 string。
到底该怎样限制 res 的类型,让它同时满足 number 和 string 的类型检查呢?这就涉及到我们今天要学的 TypeScript 的另一种类型声明——联合类型。
关于联合类型
从字面意思来看,所谓“联合类型”其实就是多种类型的联合,也就是不仅仅一种类型。
联合类型(Union Types)可以通过管道(|)给变量设置多种类型,赋值时可以根据设置的类型来赋值。
基本语法如下:
代码语言:html复制let tag:Type1|Type2|Type3
其中使用“|”分隔的三种类型代表变量 tag 可被赋值的类型范围。
注意:对于指定了联合类型的变量,其值的类型必须只能是联合类型中包含的某一种,如果取了联合类型之外的类型值,在编译过程中会报错。
指定了联合类型的变量可以在运行过程中被赋予联合类型中的任一类型值。
实际使用示例
以下是联合类型的几种实际应用举例。
声明变量
代码语言:html复制let res: number | string; // 联合类型声明
if (userInfo.age > 12) {
res = userInfo.age;
} else {
res = userInfo.name;
}
return res;
上例中的 res 只能赋值为 number 类型或 string 类型,赋值其它类型会产生报错。
函数传参
我们在函数传参中也可以使用联合类型来控制参数的预期类型:
代码语言:html复制function sayRes(res: number | string){
console.log(res);
}
sayRes(true); // Error: 类型“boolean”的参数不能赋给类型“string | number”的参数。
联合类型数组
对于可能由不同单一类型元素组成的数组声明,我们也可以使用联合类型进行声明。
代码语言:html复制let arr5: number[] | string[];
arr5[0] = true; // Error: 不能将类型“boolean”分配给类型“string | number”。
扩展知识
针对联合类型的数据,主要扩展以下几点。
只能访问共有属性或方法
一般情况下,使用联合类型是因为不能确定变量最终值的类型。
对于联合类型的变量或参数,如果不能确定其具体类型的时候,只能访问联合类型中所有类型共有的属性或方法,若访问某一类型独有的属性或方法,会产生报错。
代码语言:html复制function sayRes(res: number | string) {
if (res.length > 0) { // Error: 类型“number”上不存在属性“length”。
}
}
当 res 为 number 类型时,是不存在 .length
属性的,所以会报错。
下面这个例子中,因为 .toString()
是 number 和 string 类型共有的方法,所以可正常编译:
function sayRes(res: number | string) {
if (res.toString() === "12") {
}
}
类型推断
对于联合类型变量,在赋值后会根据值的类型推断该变量的类型。
代码语言:html复制let res :number | string;
res = "编程三昧";
console.log(res.length);
res = 12;
console.log(res.length); // Error: 类型“number”上不存在属性“length”。
在给 res 赋值为 12 后,TypeScript 推断 res 的类型为 number,number 类型不存在 .length
属性,所以报错。
总结
以上就是 TypeScript 联合类型的相关知识,总结起来就是:
- 联合类型包含了变量可能的所有类型;
- 对联合类型变量赋值为联合类型之外的值,会产生报错;
- 在不能确定联合类型变量的最终类型之前,只能访问联合类型所共有的属性和方法。
~ 本文完,感谢阅读!