在TS中和联合类型(union type)对应的还有交叉类型(intersection type)。
交叉类型的出现主要为了组合多个对象类型(object type),因为相对于interface,object type没法继承,那么就可以通过union type来实现混合的目的,从而实现继承的功能。
type objtype1 = {a: string}
type objtype2 = {b: string}
type objtype = objtype1 & objtype2function logObj(obj: objtype) {console.log(obj.a, obj.b)
}
经过objtype1和objtype2交叉objtype 变成了 {a: string, b: string}
。现在的问题是为什么两个对象类型的交叉是两个对象类型的和?
我们知道联合和交叉都是针对集合的运算,两个集合的交叉应该是集合相交的部分:
type type1 = 1 | 2
type type2 = 1 | 3
type typea = type1 & type2
这时的typea
是1
,这个很好理解,因为type1
是1 | 2
,可以看成一个集合,这样两个结合的交集就是1
这个类型。
我认为要解释两个对象类型的交叉结果是两个对象类型的和,这个问题需要结合类型兼容性去理解。
interface Pet {name: string;
}
let pet: Pet;let dog = { name: "Lassie", owner: "Rudd Weatherwax" };
pet = dog;
上面Pet类型的变量pet可以被dog对象赋值,而dog类型是{name: string, owner: string}
,所以简理解为Pet和类型{name: string, owner: string}
是兼容的,而兼容的方式可以简单理解type Pet = {name: string} | {name: string, owner: string}
这样Pet就成了一个集合,而这个集合参与交叉的时候自然会的出和的结果。结论就是一个对象类型在某种情况下表示的是自身类型+任意额外类型组合组成的一个集合。
所以在参与交叉的时候:
type objtype1 = {a: string}
可以被看成
type objtype = {a: string} | {a: string, b: string}
type objtype2 = {b: string}
可以被看成
type objtype2 = {b: string} | {b: string, a: string}
这样两个集合的交集就能得到目标类型{a: string, b: string}
。
以上是我对交叉类型作用于对象类型的个人理解,并没有找到相关文档给予的支持,仅供参考。