type
首先介绍下type
关键字,它表示类型别名,也就是说我们可以自定义一个类型。
如下我们定义了一个即可以为数字也可以为字符串的变量
// |为联合类型,下面马上说到
type sn = string | number
let sval:sn = '1'
let nval:sn = 1
联合类型
有时候我们并不确定一个变量的具体类型,他可能是一个字符串,也可能是一个数字,甚至可能是undefined。在这种情况下我们就可以使用联合类型来定义类型。
//定义一个可能为字符串,数字,或者undefined的类型
type nsu = number | string | undefined
let nval:nsu = 1
let sval:nsu = '1'
let uval:nsu = undefined
let bval:nsu = false //Type 'false' is not assignable to type 'nsu'.
它还可以限定为某几个具体的值
type xdV = '1' | '2' | '3'
let sdv1:xdV = '1'
let sdv2:xdV = '2'
let sdv3:xdV = '3'
let sdv4:xdV = 1
我们往往对复杂类型合并后,在使用的时候需要限定范围(后面代码使用了interface
接口,接口直通车)
interface A {
name: string
}
interface B {
age: string,
name: string
}
type AB = A | B
function demo(ab: AB):void {
console.log(ab.age) //报错
}
在函数里面,我们定义了形参为联合类型AB,但是并不确定是A还是B,所以直接在里面使用age属性是错误的,我需要在使用前提前就知道有没有age属性。
function demo(ab: AB):void {
if ('age' in ab) {
console.log(ab.age)
}
}
in 运算符用于检查对象是否具有指定的属性
交叉类型
交叉类型是用于将多个类型合并成一个类型的语法形式。使用交叉类型可以同时为变量指定多个类型的特性。
如下我们定义了一个手机外观的接口和一个手机价格,型号的接口。我们使用交叉类型合并这两个接口。
interface Appearance {
color: string,
thickness: number
}
interface Other {
price: number,
brand: string
}
type Phone = Appearance & Other
let p1:Phone = {
color: 'red',
thickness: 10,
price: 1999,
brand: 'xiaomi'
}
既然是合并操作,那么肯定会遇到属性重复的情况。
1.基础类型合并
interface A {
name: string;
age: number;
gender: string;
}
interface B {
name: string;
address: string;
gender: boolean;
}
type C = A & B;
const person: C = {
name: "John",
age: 30,
address: "123 Main St",
gender: false //报错
};
我们可以思考下上面代码中的gender会是什么类型?按照合并逻辑他应该既是字符串又是数字的类型,但是ts并不存在这样的类型,所以会被赋值为never类型。
2.非基础类型合并
对于非基础类型的合并,往往会整合所有属性。
interface A {
x: {
d: boolean } }
interface B {
x: {
e: string } }
interface C {
x: {
f: number } }
type ABC = A & B & C;
let abc: ABC = {
x: {
d: true,
e: 'semlinker',
f: 666
}
};