本文将简述类型系统中的类型联合,通俗的来说就是将一个变量规定为不是某一个类型,而是某些类型,我们在日常开发中很常见下面会给出例子。
值类型
在JavaScript中用const声明的变量是不可以再次赋值的,也就是常量。在TypeScript中也可以用一个值来约束变量,作用其实和const声明的变量差不多。
let a: "abc" = "abc";
a = "def" // 报错 不能将类型“def”分配给“abc”
这个例子表明:a变量的类型是字符串“abc”,导致这个变量只能赋值为"abc",赋值其他字符串就会报错。
在TypeScript中,如果遇到const声明的变量并且没有进行类型约束,那么就会将其识别为值类型。
const x = "hello"
x = "hi" // 报错 无法分配到"x" 因为是常量
这样推断是合理的,因为const
命令声明的变量,一旦声明就不能改变,相当于常量。值类型就意味着不能赋为其他值。
注意:用const声明的变量,如果赋值为对象并不会推断为值类型,因为在JavaScript中对象的属性是可以改变的
在日常开发中,单个值类型的作用不大也不常用,往往是将多个值类型联合起来使用。
联合类型
联合类型是指:多个类型组成一个新的类型,多个类型之间用符号 | 连接
联合类型A | B表示:必须满足类型A或者类型B。
let x: number | string
x = 2
x = "123"
此时的x既可以是number类型,也可以是string类型。
联合类型也可以和值类型相结合,举一个很简单的例子:
let sex: "男"|"女"
性别只能是男或者女,这样用值类型和联合类型相结合进行的约束,这样可以清楚的规定好变量的取值范围,不至于犯错。当然也可以将null和undefined类型联合进去。
当我们是用联合类型时,要注意类型缩小的问题:
function parse(s: string | number) {
console.log(s.toUpperCase()) // 报错 类型“number”上不存在属性“toUpperCase”
}
此时我们需要在函数内部将类型缩小
function parse(s: string | number) {
if (typeof s === "string") {
console.log(s.toUpperCase());
} else {
console.log(s);
}
}
交叉类型
交叉类型也是将多个类型组合为一个新的类型,类型之间用 & 连接。
A&B 表示必须同时满足A类型和B类型。
交叉类型主要用于对象之间的组合。
let a :{x:number}&{y: string}
a = {
x: 1,
y: "2"
}
变量a必须同事满足两个类型才可以成功赋值。
类型别名 type
类型别名是定义一个类型的关键字,将类型定义好之后,不同的地方约束类型的时候可以复用,减少代码的冗余。
type
命令用来定义一个类型的别名。
type Person = {
name: string
age: number
sex: "男" | "女"
job: string
}
let Tom: Person = {
name: "Tom",
age: 20,
sex: "男",
job: "外卖小哥"
}
别名可以让类型的名字变得更有意义,也能增加代码的可读性,还可以使复杂类型用起来更方便,便于以后修改变量的类型。(类型别名不可以重名!!!)
type定义的类型别名是类型相关的代码,在编译为JavaScript之后就会全部消失。
其他常用类型
void: 通常用于函数的返回值,表示函数没有任何返回值
never 通常用于约束函数的返回值,表示函数永远不会结束