type
type 关键字用来定义一种类型
举个例子
type Methods = 'GET' | 'POST' | 'PUT' | 'DELETE'
let method: Methods
method = 'PUT' // OK
method = 'aaa' // error
交叉类型
表示将多个类型合并为一个类型,多用在混入
function mixin <T, U>(first: T, later: U): T & U {
// let res = <T & U>{}
let res = {} as T & U
for (let id in first) {
(<any>res)[id] = (<any>first)[id];
}
for (let id in later) {
if (!(res as any).hasOwnProperty(id)) {
(<any>res)[id] = (<any>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 (<Fish>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)通过 ===, !== 比较时,才会被识别为类型保护