TypeScript 入门教程之类型保护
类型保护
Typescript 能够在特定的区块中保证变量属于某种特定的类型; 可以在此区块中放心的引用此类型的属性,或者调用此类型的方法
下面我们来看个例子
class Duck {
fly() {}
layEggs() {}
}
class Bird {
run() {}
layEggs() {}
}
function getAnimal(): Duck | Bird {
// ...
}
let animal = getAnimal();
animal.layEggs()
animal.fly()
如上所示, getAnimal 函数中,既可以返回 Dock 类型的对象,又可以返回 Bird 类型的对象。由于返回的对象类型不确定,所以使用联合类型对象共有的方法时,一切正常,但是使用联合类型对象各自独有的方法时, animal.fly() ts 会报错。
那怎么解决了
- 类型断言
class Duck {
fly() {}
layEggs() {}
}
class Bird {
run() {}
layEggs() {}
}
function getAnimal(): Duck | Bird {
// ...
}
let animal = getAnimal();
animal.layEggs()
if (animal as Duck) {
(animal as Duck).fly()
} else {
(animal as Bird).run()
}
类型断言虽解决了问题,但是代码的可读性却大大降低了,有没有更好的办法了,答案是肯定的。
- in 语法
使用 in 语法来判断指定的属性是否在指定的对象或其原型链中
class Duck {
fly() {}
layEggs() {}
}
class Bird {
run() {}
layEggs() {}
}
function getAnimal(): Duck | Bird {
// ...
}
let animal = getAnimal();
animal.layEggs()
if ('fly' in animal) {
animal.fly()
} else {
animal.run()
}
- instanceof 语法
联合类型中使用的是 class 而不是 interface 时,instanceof 语法就派上用场了,通过 instanceof 语法可以区分不同的 class 类型
class Duck {
fly() {}
layEggs() {}
}
class Bird {
run() {}
layEggs() {}
}
function getAnimal(): Duck | Bird {
// ...
}
let animal = getAnimal();
animal.layEggs()
if (animal instanceof Duck) {
animal.fly()
} else {
animal.run()
}
- typeof 语法
function getAnimal(): number | string {
// ...
}
let animal = getAnimal();
if (typeof animal === 'number') {
animal.fly()
} else {
animal.run()
}
- 类型函数判断
class Duck {
fly() {}
layEggs() {}
}
class Bird {
run() {}
layEggs() {}
}
function isDuck(animal: Duck | Bird): animal is Duck {
return (animal as Duck).fly !== undefined
}
function getAnimal(): Duck | Bird {
...
}
let animal = getAnimal();
animal.layEggs()
if (isDuck(animal)) {
animal.fly()
} else {
animal.run()
}