type
type
关键字用来定义一种类型
举个例子
type Methods = 'GET' | 'POST' | 'PUT' | 'DELETE'
let method: Methods
method = 'PUT' // OK
method = 'aaa' // error
交叉类型
表示将多个类型合并为一个类型,多用在混入
function mixin (first: T, later: U): T & U {
// let res = {}
let res = {} as T & U
for (let id in first) {
(res)[id] = (first)[id];
}
for (let id in later) {
if (!(res as any).hasOwnProperty(id)) {
(res)[id] = (later)[id];
}
}
return res
}
联合类型
表示变量可能的类型
let a : number | string
a = 1
a = 'test'
标识为联合类型的变量,只能调用联合类型共有的属性或者方法
class Bird {
fly () {
console.log('fly')
}
eat () {
console.log('bird eat..')
}
}
class Fish {
swim () {
console.log('swim')
}
eat () {
console.log('fish eat..')
}
}
function getAnimal (): Bird|Fish {}
getAnimal().eat()
getAnimal().swim // error
类型保护
继续上面的例子
假设我们确实要访问非共有属性或者方法,可以使用类型断言
// 使用类型断言
(getAnimal() as Fish).swim();
(getAnimal() as Bird).fly();
这样的话我们不得不多次使用类型断言,假若我们一旦检查过类型,就能在之后的每个分支里清楚地知道类型的话就好了。
类型保护就可以做到,类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型。 要定义一个类型保护,我们只要简单地定义一个函数,它的返回值是一个 类型谓词:
function isFish(pet: Fish | Bird): pet is Fish {
return (pet).swim !== undefined;
}
pet is Fish
就是类型谓词。 谓词为 parameterName is Type
这种形式,parameterName
必须是来自于当前函数签名里的一个参数名
通过类型保护,typeScript 可以推断 if
分支的 pet
一定是 Fish
,else
分支的一定是 Bird
let pet = getAnimal()
if (isFish(pet)) {
pet.swim()
} else {
pet.fly()
}
此外也可以使用 typeof
,instanceof
做类型保护
function checkType (val: number | string) {
if (typeof val === 'number') {}
if (typeof val === 'string') {}
}
function checkInstance (val: Bird | Fish) {
if (val instanceof Bird) {}
if (val instanceof Fish) {}
}
注意, typeof
只有和基本类型(number,string,boolean,symbol
)通过 ===, !==
比较时,才会被识别为类型保护