交叉类型

将多个类型合并成为一个新的类型,新类型具有所有类型的特性 场景: 交叉类型具有所有类型的特性,非常适合对象混入的场景 语法: A & B 注意: 交叉类型中的交叉,并不是指两个类型的交集,而是并集

  1. interface DogInterface {
  2. run(): void;
  3. }
  4. interface CatInterface {
  5. jump(): void;
  6. }
  7. // 交叉类型:取所以类型的并集
  8. let pet: DogInterface & CatInterface = {
  9. run() {},
  10. jump() {},
  11. };

联合类型

简单的联合类型

联合类型:类型可能为多个类型中的一种,但不能确定是哪一种

  1. let strA: number | string = "a";
  2. let strB: "a" | "b" | "c";

字面量联合类型

不仅限定变量类型,还限定变量的取值范围

  1. let strC: 1 | 2 | 3;
  2. let strD: "1" | "2" | "3" = "1";

对象联合类型

  1. // 定义两个类,分别实现两个接口
  2. class Doga implements DogInterface {
  3. run() {}
  4. eat() {}
  5. }
  6. class Cata implements CatInterface {
  7. jump() {}
  8. eat() {}
  9. }
  10. // 定义枚举 Master
  11. enum Master {
  12. Boy,
  13. Girl,
  14. }
  15. // 根据类型获取实例
  16. function getPet(master: Master) {
  17. let pet = master === Master.Boy ? new Doga() : new Cat();
  18. pet.eat();
  19. // pet.run()
  20. return pet;
  21. }

可区分的联合类型

本质上是结合联合类型和字面量类型的一种类型保护方法 如果一个类型是多个类型的联合类型,且多个类型间有一个公共属性。那么,就可以利用这个公共属性,创建不同的类型保护区块

  1. // 正方形
  2. interface Square {
  3. kind: "square";
  4. side: number; // 边长
  5. }
  6. // 长方形
  7. interface Rectangle {
  8. kind: "rectangle";
  9. width: number; // 宽
  10. height: number; // 高
  11. }
  12. // 圆
  13. interface Circle {
  14. kind: "circle";
  15. r: number; // 半径
  16. }
  17. type Shape = Square | Rectangle | Circle;
  18. // 计算面积: 利用两种类型共有的kind属性,创建不同的类型保护区块
  19. // function area(s: Shape): number {
  20. function area(s: Shape) {
  21. switch (s.kind) {
  22. case "square":
  23. return s.side * s.side;
  24. case "rectangle":
  25. return s.height * s.width;
  26. case "circle":
  27. return Math.PI * s.r ** 2;
  28. default:
  29. // 在default中检查未被之前case捕捉到的类型是否为never类型;
  30. // 如果s是never类型, 说明前面的所有分支都被覆盖了, 这个分支永远不会走到;
  31. // 如果s不是never类型, 说明前面的分支有遗漏, 需要补上这个分支;
  32. return ((e: never) => {
  33. throw new Error(e);
  34. })(s);
  35. }
  36. }
  37. console.log(area({ kind: "circle", r: 1 })); // 3.141592653589793