前言
ts入门了一段时间,可是碰上一些高级类型总是一头雾水,还需要去看文档,所以总结了一些工作中经常用到的一些高级类型。所以阅读之前你需要掌握一点儿ts基础。
一、交叉类型
交叉类型将多个类型合并为一个新的类型,新的具有所有参与合并的类型的特性,本质上是一种并的操作。形式如下:
T & U
//例子:
function extend<T , U>(first: T, second: U) : T & U {
let result: <T & U> = {}
for (let key in first) {
result[key] = first[key]
}
for (let key in second) {
if(!result.hasOwnProperty(key)) {
result[key] = second[key]
}
}
return result
}
二、联合类型
联合类型用 | 分割每一个类型,表示只能取其中的一种类型,比如: number | string | boolean 的类型只能是这三个的一种,不能共存。
如果一个值的类型是联合类型,那么我们只能访问它们中共有的属性或者方法,本质上是一种交的关系,比如:
interface Cat {
eat(food) : void
miao() : string
}
interface Dog {
eat(food) : void
wang() : string
}
function getPet() : Cat | Dog {
...
}
let pet = getPet()
pet.eat() //正确
pet.miao() //报错
三、类型保护与类型区分
联合类型让一个值可以为不同的类型,但随之带来的问题就是访问非共同方法时会报错。那么该如何区分值的具体类型,以及如何访问共有成员?
1.使用类型断言
let pet = getPet()
if((<Cat>pet).miao) {
(<Cat>pet).miao()
} else {
(<Dog>pet).wang()
}
可见使用类型断言就不得不写一堆蹩脚的尖括号,那么还没有更简洁明了办法来判断类型呢?
2.使用类型保护
function isCat(pet: Cat | Dog) : pet is Cat {
return (<Cat>pet).miao !== undefined
}
这种param is SomeType 的形式就是类型保护,我们可以用它来明确一个联合类型变量的具体形式,在调用时ts就会将变量缩减为该具体类型,调用就是合法的了
if (isCat(pet)) {
pet.miao() //正确
} else {
pet.wang()
}
允许这么做是因为:typescript能够通过类型保护知道if语句里的pet类型一定是Fish类型,而且else语句里的pet类型一定不是Fish类型,那么就是Bird类型了
3.type 和instanceof
当我们使用了typeof和instanceof后,typescript就会自动限制类型为某一具体类型,从而我们可以安全