交叉类型
- 格式: type1 & type2 & ...
- 交叉类型是将多个类型合并为一个类型
let mergeFn = <T, U>(arg1: T, arg2: U): T & U => {
let res = {} as T & U
res = Object.assign(arg1, arg2)
return res
}
let res = mergeFn({ name: 'cs' }, { age: 11 })
console.log('res', res)
联合类型
- 格式: type1 | type2 | ...
- 联合类型是多个类型中的任意一个类型
// 联合类型
let value: string | number
value = 'abc'
value = 123
}
类型保护
- 对于联合类型的变量,在使用时如何确切告诉编译器他是哪一种类型
- 主要有类型断言和类型保护
let getRandomValue = (): string | number => {
let num = Math.random()
return num >= 0.5 ? 'abc' : 123.3
}
// 无法得知res1返回值类型
let res1 = getRandomValue()
console.log('res1', res1)
- 方式一
- 虽然类型断言可以确切告诉编译器当前的变量是什么类型
- 但是每一次使用的时候都需要手动告诉编译器, 这样比较麻烦
if ((res1 as string).length) {
console.log((res1 as string).length)
} else {
console.log((res1 as number).toFixed())
}
- 方式二
- 定义一个类型保护函数, 这个函数的返回类型是布尔类型
- 这个函数的返回值是, 传入的参数 + is 具体类型
function isString(value: string | number): value is string {
return typeof value === 'string'
}
if (isString(res1)) {
console.log((res1 as string).length)
} else {
console.log((res1 as number).toFixed())
}
- 方式三
- 使用 typeof 来实现类型保护
- 如果使用 typeof 来实现类型保护, 那么只能使用 === 或者 !==
- 如果使用typeof 来是实现类型保护, 那么只能保护 number/ string/ boolean/ symbol类型
if (typeof res1 === 'string') {
console.log((res1 as string).length)
} else {
console.log((res1 as number).toFixed())
}
- 可以通过typeof来是来实现类型保护以外, 我们可以使用 instance
class Person {
name: string = 'css'
}
class Animal {
age: number = 12
}
let getRandomObject = (): Person | Animal => {
let num = Math.random()
return num >= 0.5 ? new Person() : new Animal()
}
let obj = getRandomObject()
console.log('obj', obj)
if (obj instanceof Person) {
console.log(obj.name)
} else {
console.log(obj.age)
}
}