类型保护 - 10

类型保护

  • 类型保护就是一些表达式,他们在编译的时候就能通过类型信息确保某个作用域内变量的类型
  • 类型保护就是能够通过关键字判断出分支中的类型

1 typeof 类型保护

function double(input: string | number | boolean) {
  if (typeof input === "string") {
    input.toLocaleLowerCase()
  } else if (typeof input === "number") {
    input.toFixed()
  } else {
    input
  }
}

2 instanceof 类型保护

class Animal {
  public name: string = "ruhua"
}
class Bird extends Animal {
  public swing: number = 2;
}
function getName(a: Animal) {
  if (a instanceof Bird) {
    a.swing;
    a.name;
  } else {
    // a.swing; // 报错
    a.name;
  }
}

3 null 类型保护

function getFirstLetter(s: string | null) {
  if (s === null) {
    s = ""
  }
  return s.charAt(0)
}

4 链判断运算符

  • 链判断运算符是一种先检查属性是否存在,在尝试访问该属性的运算符,其符号为 ?.
  • 如果运算符左侧的操作数 ?. 计算为 undefined 或 null,则表达式求值为 undefined。否则,正常触发目标属性访问,发放或函数调用
a?.b;
a == null ? undefind : a.b;

a?.[x];
a == null ? undefind : a[x];

a?.b();
a == null ? undefind : a.b();

a?.();
a == null ? undefind : a();

链判断运算符还处于 stage1 阶段(征求意见阶段),TS 也暂时不支持

5 可辨识的联合类型

  • 就是利用联合类型中的共有字段进行类型保护的一种技巧
  • 相同字段的不同取值就是可辨识
interface WarningButton {
  class: "warning", // 字面量类型
  text1: "修改"
}
interface DangerButton {
  class: "danger",
  text2: "删除"
}
type Button = WarningButton | DangerButton;
function getButton(button: Button) {
  if (button.class === "warning") {
    button.text1
  } else {
    button.text2
  }
}

6 in 操作符

interface Bird {
  swing: number
}
interface Dog {
  leg: number
}
function getNumber(x: Bird | Dog) {
  if ("swing" in x) {
    x.swing
  } else {
    x.leg
  }
}

7 自定义的类型保护

  • TS 里的类型保护本质上就是一些表达式,他们会在运行时检查类型信息,以确保在某个作用域里的类型是符合预期的
  • 要自定义一个类型保护,只需要简单地为这个类型保护定义一个函数即可,这个函数的返回值是一个类型谓词
  • 类型谓词的语法为 parameterName is Type 这种形式,其中 parameterName 必须是当前函数签名里的一个参数名
  interface Bird {
    name1: "bird"
    legs: number
  }
  interface Dog {
    name2: "dog"
    legs: number
  }
  function isBird(x: Bird | Dog): x is Bird {
    return x.legs === 2;
  }
  function getAnimal(x: Bird | Dog) {
    if (isBird(x)) {
      console.log(x.name1); // x 是 Bird 类型
    } else {
      console.log(x.name2); // x 是 Dog 类型
    }
  }

  let x: Bird = { name1: "bird", legs: 2 }
  getAnimal(x)
posted @ 2022-05-29 23:06  真的想不出来  阅读(29)  评论(0)    收藏  举报