如果我键入以下内容:
interface A {
x: number
}
interface B {
y: number
}
type Z = A | B;
// here it allows me to create a variable of type Z with both members of type A and B.
let z: Z = {
x: 5,
y: 6,
}
我无法确保Z类型的对象确实包含A的所有成员但不包含B的成员(或相反的成员)。 TypeScript有可能吗?经过大量的研究,我倾向于" no"回答,但我不确定。
答案 0 :(得分:4)
默认情况下,联盟将所有选项合并为一个,但有两种选择。 TypeScript中没有您想要的内容,但TS项目列表中存在类似问题(状态:此时为“打开”)以及两个不错的解决方法。
一个选项不可用:目前TypeScript中没有确切的类型(unlike in Flow)。 TS问题#12936 "Exact Types"现在仍然是开放的。
在TS的公开问题列表中还有另一个问题/建议,它会准确询问您的问题:#14094 "Proposal: Allow exclusive unions using logical or (^) operator between types"
在TypeScript和Flow中,您可以使用标记类型来创建XOR联合而不是OR联合。
interface A {
kind: 'A',
x: number
}
interface B {
kind: 'B',
y: number
}
type Z = A | B;
// here it DOES NOT allow to create a variable of type Z with both members of type A and B.
let z: Z = {
kind: 'A',
x: 5
// y: 6 will produce an error
}
第二个选项是设置所有类型的所有属性,但将那些不应存在的属性设置为undefined
:
interface A {
x: number,
y?: undefined
}
interface B {
x?: undefined,
y: number
}
type Z = A | B;
let z: Z = {
y: 5
// y: 6 will produce an error
}
为了记录,在Facebook的类型系统Flow中,您可以通过使用不相交的联合(XOR)而不仅仅是联合(OR)或使用确切的对象类型来解决问题或者就上面的TS而言,将不良属性设置为undefined
。 I made a Flow demo with your example (link)。在这种情况下,Flow的代码与TS相同。