一、类型保护
类型保护又叫类型守卫,是为了提高程序的鲁棒性存在的。先来看一个例子:
enum Type { JavaScript , Python };
class JavaScript {
helloJS(){
console.log("hello JavaScript!");
}
}
class Deno {
helloDeno(){
console.log("hello deno!");
}
}
function getLangage(type:Type):void{
const lang = type === 0 ? new JavaScript() : new Deno();
if(lang.helloJS){//报错
lang.helloJS();
}else{
lang.helloDeno();
}
console.log(lang);
}
getLangage(Type.JavaScript);
上面的代码 lang 使用三元来赋值的,lang 是一个联合类型,const lang: JavaScript | Deno 无法准确确定 lang 的值,所以条件语句里的代码为了防止出错,应为使用类型断言。条件语句的代码改写为:
if((lang).helloJS){
(lang).helloJS();
}else{
(lang).helloDeno();
}
现在没问题了,但是每个地方我们都加了类型断言,很明显这种方案不是我们想要的可读性差写起来也是很麻烦类型守卫就是解决这个问题的。可以简单理解为类型保护就是解决类型断言可读性差和书写不方便的。
类型保护:能够在特定的区块中(比如函数里)保证变量属于某种特定的类型,可以在区块中放心的使用此类型的属性或方法。
下面介绍四种,还使用上面的案例,只改动条件判断语句:
instanceof
if(lang instanceof JavaScript){
lang.helloJS();
}else{
lang.helloDeno();
}
使用 in ,属性名是否在对象中
enum Type { JavaScript , Python };
class JavaScript {
JS:any;
helloJS(){
console.log("hello JavaScript!");
}
}
class Deno {
Py:any;
helloDeno(){
console.log("hello deno!");
}
}
function getLangage(type:Type):void{
const lang = type === 0 ? new JavaScript() : new Deno();//const lang: JavaScript | Deno
if("JS" in lang){
lang.helloJS();
}else{
lang.helloDeno();
}
console.log(lang);
}
getLangage(Type.JavaScript);
typeof 检测基本类型的方法
function main(x:string | number){
if(typeof x === "string"){
console.log("x is string");
}else {
console.log("x is number");
}
}
main(12);
类型保护函数
要定义一个类型守卫,我们只要简单地定义一个函数,它的返回值是一个类型谓词:
enum Type { JavaScript , Python };
class JavaScript {
JS:any;
helloJS(){
console.log("hello JavaScript!");
}
}
class Deno {
PY:any;
helloDeno(){
console.log("hello JavaScript!");
}
}
function getLangage(type:Type):void{
const lang = type === 0 ? new JavaScript() : n