# 九.类型保护

前言

通过判断识别所执行的代码块,自动识别变量属性和方法

# 1.typeof

判断变量类型,对不同类型进行不同的处理

function getDouble(val: number | string) {
  if (typeof val === "number") {
   return val*val
  } else {
   return  Number(val) * Number(val)
  }
}
1
2
3
4
5
6
7

# 2.instanceof

判断实例类型,对不同实例进行不同操作

class Cat {
  getRes(){
    console.log('aaa')
  }
}
class Dog {
   getRes(){
    console.log('bbb')
  }
}
const getInstance = (fn: { new (): Cat | Dog }) => {
  return new fn();
};
let instance = getInstance(Cat);

function getRes (){
if (instance instanceof Cat) {
   return instance.getRes();
  } else {
   return instance.getRes();
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Padder {
  getPaddingString(): string;
}
class SpaceRepeatingPadder implements Padder {
  constructor(private numSpaces: number) {}
  getPaddingString() {
    return Array(this.numSpaces + 1).join(" ");
  }
}
class StringPadder implements Padder {
  constructor(private value: string) {}
  getPaddingString() {
    return this.value;
  }
}
let padder: Padder = new SpaceRepeatingPadder(6);
if (padder instanceof SpaceRepeatingPadder) {
  // padder的类型收窄为 'SpaceRepeatingPadder'
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3.in

通过判断是否在某个类型中,进行不同的处理

interface Fish {
  swiming: string;
}
interface Bird {
  fly: string;
  leg: number;
}
function getType(animal: Fish | Bird) {
  if ("swiming" in animal) {
    animal; // Fish
  } else {
    animal; //Bird
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 4.可辨识联合类型

interface WarningButton {
  class: "warning";
}
interface DangerButton {
  class: "danger";
}
function createButton(button: WarningButton | DangerButton) {
  if (button.class === "warning") {
    button; // WarningButton
  } else {
    button; //DangerButton
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.null 保护

const addPrefix = (num?: number) => {
  num = num || 1.1;
  function prefix(fix: string) {
    return fix + num?.toFixed();
  }
  return prefix("aaa");
};
console.log(addPrefix());
1
2
3
4
5
6
7
8

这里要注意的是 ts 无法检测内部函数变量类型

# 6.自定义类型保护

interface Fish {
  swiming: string;
}
interface Bird {
  fly: string;
  leg: number;
}
function isBird(animal: Fish | Bird): animal is Bird {
  return "swiming" in animal;
}
function getAniaml(animal: Fish | Bird) {
  if (isBird(animal)) {
    animal;
  } else {
    animal;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 7.完整性保护

interface ICircle {
  kind: "circle";
  r: number;
}
interface IRant {
  kind: "rant";
  width: number;
  height: number;
}
interface ISquare {
  kind: "square";
  width: number;
}
type Area = ICircle | IRant | ISquare;
const isAssertion = (obj: never) => {};
const getArea = (obj: Area) => {
  switch (obj.kind) {
    case "circle":
      return 3.14 * obj.r * 2;
    default:
      return isAssertion(obj); //必须实现所有逻辑
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 8. ⾃定义类型保护的类型谓词

function isNumber(x: any): x is number {
  return typeof x === "number";
}
function isString(x: any): x is string {
  return typeof x === "string";
}
1
2
3
4
5
6