简述

  • 交叉类型是将多个类型合并为一个类型,这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。
  • 交叉类型,可以赋予给没有交叉之前的2个类型,也就是说,算是2个类型的子类型。
  • 注意:和数学中的交集不太一样
  1. interface Bird{
  2. name:string;
  3. fly():void;
  4. }
  5. interface Person{
  6. name:string;
  7. talk():void;
  8. }
  9. // 咋一看,类似取 Bird 和 Person 的并集,其实是取属性的交集,范围更小了。
  10. // 差不多就相当于,取鸟中能说话的,取人中能飞的。
  11. // BirdPerson 要兼容 Bird 和 Person,BirdPerson类型声明的变量 要可以赋值给Bird或者Person类型声明的变量
  12. // 也就是说,BirdPerson是 Bird 和 Person 的子类型
  13. type BirdPerson = Bird & Person;
  14. let p:BirdPerson = {
  15. name: 'jack',
  16. fly(){},
  17. talk(){},
  18. }
  19. p.fly();
  20. p.talk();
  21. let bird:Bird = p;
  22. let person:Person = p;
  23. //交叉类型可以不生成一个新的类型,作为临时类型使用
  24. let p2:(BirdPerson & {sleep:string}) = {...p, sleep: '睡觉'}

联合类型的交叉类型

  1. type R = (string|number) & (number|boolean); //=> R类型为 number

同一属性的交叉

  1. interface X {
  2. a: string|number,
  3. b: number;
  4. }
  5. interface Y {
  6. a: number|boolean;
  7. c: string;
  8. }
  9. type XY = X & Y;
  10. type YX = Y & X; // => XY、YX其实结果是一样的, {a: number, b: number, c: string}
  11. const xy:YX = {a: 1, b:1, c: ''}; //正确

如果两个类型不一样,则相交的结果是never

  1. type Other = string & never; //Other的类型是never
  2. interface X {
  3. a:string,
  4. }
  5. interface Y{
  6. a:number,
  7. }
  8. type XY = X & Y;
  9. //a属性的类型是string和number,交叉后为never类型,所以X和Y不能交叉

实例应用:mixin

mixin混入模式可以让你从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能。

  1. function mixin<T extends object, U extends object>(one:T, two:U):(T&U){
  2. let result = <T&U>{};
  3. for (let k in one){
  4. (result as T)[k] = one[k];
  5. }
  6. for (let k in two){
  7. (result as U)[k] = two[k];
  8. }
  9. return result;
  10. }
  11. //后续真正合并属性的时候,要以一方为基础,不会直接相交,可能会导致never情况
  12. // 类似于webpack-merge
  13. let x = mixin({name: 'jack'}, {age: 18});
  14. console.log(x.name, x.age); //jack 18