类型保护
- 类型保护就是一些表达式,他们在编译的时候就能通过类型信息确保某个作用域内变量的类型
- 类型保护就是能够通过关键字判断出分支中的类型
typeof 类型保护
function double(input:string|number|boolean){
if(typeof input === 'string'){
return input + input;
}else {
if(typeof input === 'number'){
return input*2;
}else{
return !input;
}
}
}
instanceof 类型保护
class Animal{
name:string;
}
class Bird extends Animal{
swing:number
}
function getName(animal:Animal){
if(animal instanceof Bird){
console.log(animal.swing);
}else{
console.log(animal.name);
}
}
null 保护
function getFirstLetter(s:string|null){
if(s == null){
return '';
}
s = s || '';
return s.charAt(0);
}
function getFirstLetter2(s:string|null){
function log(){
console.log(s!.trim());
}
s = s || '';
log();
return s.charAt(0);
}
链判断运算符
- 链判断运算符是一种先检查属性是否存在,再尝试访问该属性的运算符,其符号为 ?.
- 如果运算符左侧的操作数 ?. 计算为 undefined 或 null,则表达式求值为 undefined 。否则,正常触发目标属性访问,方法或函数调用。
a?.b;
a == null ? undefined : a.b;
a?.[x];
a == null ? undefined : a[x];
a?.b();
a == null ? undefined : a.b();
a?.();
a == null ? undefined : a();
可辨识的联合类型
- 就是利用联合类型中的共有字段进行类型保护的一种技巧
- 相同字段的不同取值就是可辨识
interface WarningButton{
class:'warning',
text1:'修改'
}
interface DangerButton{
class:'danger',
text2:'删除'
}
type Button = WarningButton|DangerButton;
function getButton(button:Button){
if(button.class=='warning'){
console.log(button.text1);
}
if(button.class=='danger'){
console.log(button.text2);
}
}
in 操作符
swing: number;
}
interface Dog {
leg: number;
}
function getNumber(x: Bird | Dog) {
if ("swing" in x) {
return x.swing;
}
return x.leg;
}
自定义的类型保护
- TypeScript 里的类型保护本质上就是一些表达式,它们会在运行时检查类型信息,以确保在某个作用域里的类型是符合预期的
- 要自定义一个类型保护,只需要简单地为这个类型保护定义一个函数即可,这个函数的返回值是一个类型谓词
- 类型谓词的语法为
parameterName is Type 这种形式,其中 parameterName 必须是当前函数签名里的一个参数名
interface Bird {
swing: number;
}
interface Dog {
leg: number;
}
function isBird(x:Bird|Dog): x is Bird{
return (<Bird>x).swing == 2;
return (x as Bird).swing == 2;
}
function getAnimal(x: Bird | Dog) {
if (isBird(x)) {
return x.swing;
}
return x.leg;
}