在typescript中提供一种对象类型

时间:2017-11-15 19:04:31

标签: typescript types object-literal

如果我键入以下内容:

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"回答,但我不确定。

1 个答案:

答案 0 :(得分:4)

默认情况下,联盟将所有选项合并为一个,但有两种选择。 TypeScript中没有您想要的内容,但TS项目列表中存在类似问题(状态:此时为“打开”)以及两个不错的解决方法。

一个选项不可用:目前TypeScript中没有确切的类型(unlike in Flow)。 TS问题#12936 "Exact Types"现在仍然是开放的。

在TS的公开问题列表中还有另一个问题/建议,它会准确询问您的问题:#14094 "Proposal: Allow exclusive unions using logical or (^) operator between types"


您可以使用以下解决方法:

#1

在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
}


#2

第二个选项是设置所有类型的所有属性,但将那些不应存在的属性设置为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而言,将不良属性设置为undefinedI made a Flow demo with your example (link)。在这种情况下,Flow的代码与TS相同。