在逻辑上与联合类型互补,联合类型表示一个值的类型为多种类型之一,交叉类型则表示一个值的类型同时属于多个类型。

交叉类型字面量

由两个或多个成员类型构成,各成员类型之间使用&符号分割
与联合类型相似,如果交叉类型中存在多个相同的成员类型,那么相同的成员类型将被合并为单一成员类型
交叉类型通常与对象类型一起使用。虽然在交叉类型中也允许出现原始类型成员,但结果类型将成为never类型

交叉类型的类型成员

只要交叉类型I中任意一个成员类型包含了属性签名M,那么交叉类型I也包含属性签名M

  1. interface A {
  2. a:boolean;
  3. }
  4. interface B {
  5. b:string;
  6. }
  7. type AB = A & B
  8. {
  9. a:boolean;
  10. b:string;
  11. }

对于交叉类型的属性签名,其类型为所有成员类型中该属性类型的交叉类型

  1. interface A {
  2. x:{a:boolean}
  3. }
  4. interface B {
  5. x:{b:boolean}
  6. }
  7. type AB = A & B
  8. {
  9. x:{
  10. a:boolean;
  11. b:boolean
  12. }
  13. }

若交叉类型的属性签名M在所有成员类型中都是可选属性,那么该属性签名在交叉类型中也是可选属性

  1. interface A {
  2. x:boolean;
  3. y?:string
  4. }
  5. interface B {
  6. x?:boolean;
  7. y?:string
  8. }
  9. type AB = A & B
  10. {
  11. x:boolean;
  12. y?:string
  13. }

索引签名

如果交叉类型中任何一个成员类型包含了索引签名,那么该交叉类型也拥有了索引签名

  1. interface A {
  2. [prop:string]:string;
  3. }
  4. interface B {
  5. [prop:number]:string;
  6. }
  7. type AB = A & B
  8. {
  9. [prop:string]:string;
  10. [prop:number]:string;
  11. }
  1. interface A {
  2. [prop:string]:{a:boolean};
  3. }
  4. interface B {
  5. [prop:string]:{b:boolean};
  6. }
  7. type AB = A & B
  8. {
  9. [prop:string]:{a:boolean} & {b:boolean};
  10. }

调用签名和构造签名

需要注意的是,当交叉类型涉及调用签名重载或构造签名重载时便失去了“加法交换律”的性质。因为交叉类型中成员类型的顺序将决定重载签名的顺序,进而将影响重载签名的解析顺序。

  1. interface Clickable {
  2. register(x:any):void
  3. }
  4. interface Focusable {
  5. register(x:string):boolean
  6. }
  7. type ClickableAndFocusable = Clickable & Focusable
  8. type FocusableAndFocusable = Focusable & Clickable
  9. // 这两种类型不一样

交叉类型与联合类型

优先级

当”&”和”|”符号同时使用时,&符号有更高的优先级,&相当于乘法,|相当于加法
当”&”和”|”符号与函数类型字面量使用时,”&”和”|”拥有更高的优先级

分律配性质

  1. A & (B | C) = (A & B) | (A & C)