类型保护
- 对于联合类型的变量,在使用时如何确切告诉编译器它是哪一种类型
- 通过
类型断言
或者类型保护
如下我写了一个示例代码,就是一个 getRandomValue
函数,通过生成的随机数,来决定返回的是 string
还是 number
类型,那么我想如果是 string 类型则调用 .length 属性,如果是数字就调用 toFixed
:
let getRandomValue = (): (string | number) => {
let num = Math.random();
return (num >= 0.5) ? 'abc' : 123.123;
}
let value = getRandomValue();
console.log(value);
那么就由此得来如下这么一段代码:
let getRandomValue = (): (string | number) => {
let num = Math.random();
return (num >= 0.5) ? 'abc' : 123.123;
}
let value = getRandomValue();
console.log(value);
if (value.length) {
console.log(value.length);
} else {
console.log(value.toFixed());
}
但是通过我所编写的代码在编译器当中是会报错的,那么就来看看通过 类型断言
与 类型保护
来解决该问题吧。
通过类型断言:
let getRandomValue = (): (string | number) => {
let num = Math.random();
return (num >= 0.5) ? 'abc' : 123.123;
}
let value = getRandomValue();
console.log(value);
if ((value as string).length) {
console.log((value as string).length);
} else {
console.log((value as number).toFixed());
}
如上虽然通过 类型断言
可以确切的告诉编译器当前的变量是什么类型,但是每一次使用的时候都需要手动的告诉编译器, 这样比较麻烦, 冗余代码也比较多,那么这个时候就出现了如下的类型保护的编写方式来进行实现了。
通过类型保护:
let getRandomValue = (): (string | number) => {
let num = Math.random();
return (num >= 0.5) ? 'abc' : 123.123;
}
let value = getRandomValue();
console.log(value);
function isString(value: (string | number)): value is string {
return typeof value === 'string';
}
if (isString(value)) {
console.log(value.length);
} else {
console.log(value.toFixed());
}
除了可以通过定义 类型保护函数
的方式来告诉编译器使用时联合类型的变量具体是什么类型以外,我们还可以使用 typeof
来实现 类型保护
。
注意点
- 如果使用
typeof
来实现类型保护
, 那么只能使用===
/!==
- 如果使用
typeof
来实现类型保护, 那么只能保护number/string/boolean/symbol
类型
通过 typeof
实现类型保护:
let getRandomValue = (): (string | number) => {
let num = Math.random();
return (num >= 0.5) ? 'abc' : 123.123;
}
let value = getRandomValue();
console.log(value);
if (typeof value === 'string') {
console.log(value.length);
} else {
console.log(value.toFixed());
}
除了可以通过 typeof
类实现类型保护以外, 我们还可以通过 instanceof
来实现 类型保护
:
class Person {
name: string = 'BNTang';
}
class Animal {
age: number = 18;
}
let getRandomObject = (): (Person | Animal) => {
let num = Math.random();
return (num >= 0.5) ? new Person() : new Animal();
};
let obj = getRandomObject();
console.log(obj);
if (obj instanceof Person) {
console.log(obj.name);
} else {
console.log(obj.age);
}