「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。
1.概念
类型保护:能够在特定的区块中保证变量属于某种确定的类型,可以在此区块中放心地引用此类型的属性,或者调用此类型的方法。
为什么要引入类型保护呢?先来看一个例子:
enum Type {Strong,Week}
class Java {
helloJava() {
console.log('Java');
}
}
class JavaScript {
helloJavaScript() {
console.log('JavaScript');
}
}
function getLanguage(type: Type) {
let lang = type === Type.Strong ? new Java() : new JavaScript();
if((lang as Java).helloJava ) {
(lang as Java).helloJava();
} else {
(lang as JavaScript).helloJavaScript();
}
return lang;
}
上例中,在getLanguage方法中,先判断lang是否有helloJava方法后再执行该方法,如果没有使用类型断言则会报错,因为lang有可能是Java类型,也可能是JavaScript类型,无法判别它是否拥有helloJava属性,所以使用类型断言来对特定的类型进行特定的操作,但使用类型断言看起来很复杂,阅读性不好。因此可以使用类型保护的方法。
2. 类型保护的方式
类型保护有以下几种方式:
(1)instanceof
instanceof:判断变量是哪个类的实例,形成类型保护。
function getLanguage(type: Type) {
let lang = type === Type.Strong ? new Java() : new JavaScript();
if(lang instanceof Java) {
lang.helloJava();
} else {
lang.helloJavaScript();
}
return lang;
}
上例中,不再使用联系断言,而是使用instanceof判断变量是Java类还是JavaScript类的实例,形成类型保护,再执行对应的操作。
(2)in:判断某个属性是否属于某个对象,形成类型保护。
function getLanguage1(type: Type) {
let lang = type === Type.Strong ? new Java() : new JavaScript();
if('helloJava' in lang) {
lang.helloJava();
} else {
lang.helloJavaScript();
}
return lang;
}
上例中,使用in关键字判断helloJava属性是否在lang对象中,形成类型保护,再执行对应的操作。
(3)typeof:判断基本类型
function getX(x: string | number) {
if(typeof x === 'string') {
return x.length;
} else {
return x.toFixed(2)
}
}
上例中,使用typeof关键字判断参数x的类型,形成类型保护,再执行对应的操作。
(4)类型保护函数
类型保护函数:设置一个函数来判断参数类型。
function isJava(lang:Java | JavaScript):lang is Java {
return (lang as Java).helloJava !== undefined
}
function getLanguage2(type: Type) {
let lang = type === Type.Strong ? new Java() : new JavaScript();
if(isJava(lang)) {
lang.helloJava();
} else {
lang.helloJavaScript();
}
return lang;
}
上例中,设置了类型保护函数isJava,其中用类型断言的方式来判断参数lang的类型。getLanguage2中直接调用isJava方法进行类型判别,再执行对应操作。