TypeScript 能够在特定区块中保证变量属于某种确定的类型,可以在此区块中放心地引用此类型的属性或者调用此类型的方法。
解决的问题
enum Type {
Strong,
Week
}
class Java {
helloJava() {
}
}
class JavaScript {
helloJavaScript() {
}
}
function getLanguage(type: Type) {
let lang = type === Type.Strong ? new Java() : new JavaScript();
// 下面这种判断形式经常用到
if (lang.helloJava) { // 但是 TS 会报错,因为 TS 判断 lang 是一个联合类型,不一定具有 helloJava 方法,下面方法的调用也是一样的
lang.helloJava();
} else {
lang.helloJavaScript();
}
return lang;
}
解决上面问题的办法,可以使用类型断言:
if ((lang as Java).helloJava) {
(lang as Java).helloJava();
} else {
(lang as JavaScript).helloJavaScript();
}
但是这种办法显然非常的繁琐,此时我们就可以使用类型保护了。
触发类型保护
instanceof
使用这个关键字,可以触发类型保护:用于判断某个变量是不是某个类的实例
if (lang instanceof Java) {
// 此时 TS 可以保证在这个区块中一定是 Java 类型
lang.helloJava();
} else {
// 这个区块也被直接保证为 JavaScript 类型
lang.helloJavaScript();
}
in
使用这个关键字,可以触发类型保护:用于判断某个属性是不是属于某个对象
if ('helloJava' in lang) {
// 此时 TS 可以保证在这个区块中一定是 Java 类型
lang.helloJava();
} else {
// 这个区块也被直接保证为 JavaScript 类型
lang.helloJavaScript();
}
typeof
使用这个关键字,可以触发类型保护:用于判断某个变量的类型:
if (typeof x === 'string') {
x.length;
} else {
x.toFixed();
}
类型保护函数
通过创建一个函数来实现类型保护:
function isJava(lang: Java | JavaScript): lang is Java { // 注意返回值的类型
return (lang as Java).helloJava !== undefined;
}
if (isJava(lang)) {
// 此时 TS 可以保证在这个区块中一定是 Java 类型
lang.helloJava();
} else {
// 这个区块也被直接保证为 JavaScript 类型
lang.helloJavaScript();
}