联盟类型:一个或另一个失败。不确定这是设计还是错误

时间:2017-03-01 03:04:15

标签: typescript

考虑一种情况,即对象可以完全下面列出的FooBarBaz接口。

interface FooBar {
    foo: string;
    bar: string;
}

interface Baz {
    baz: string;
}

我的理解是,可以通过在FooBarBaz之间创建联合来处理这种“一种或另一种”情况。

type FooBarOrBaz = FooBar | Baz;

到目前为止一直很好......

我遇到的问题是以下对象传递了类型检查:

const x: FooBarOrBaz = {
    foo: 'foo',
    baz: 'foo',
};

这是一个错误吗?

Playground Example

提前致谢!

1 个答案:

答案 0 :(得分:2)

我认为这里有一个错误。

通过切换到类然后在联合类型上使用instanceof的类型缩小方面,可以使其更加明确。

从代码开始,但切换到类:

class FooBar {
    foo: string;
    bar: string;
}

class Baz {
    baz: string;
}

type FooBarOrBaz = FooBar | Baz;

像你一样创建一个实例 - 编译得很好。

const x: FooBarOrBaz = {
    foo: 'foo',
    baz: 'baz',
}

检查我们是否有FooBar

if (x instanceof FooBar) {
    console.log("x is a FooBar : (" + x.foo + "," + x.bar + ")");
} else {
    console.log("x is not FooBar must be Baz : " + x.baz);
}

此编译没有警告并打印x is not FooBar must be Baz : baz

检查我们是否有Baz

if (x instanceof Baz) {
    console.log("x is a Baz : (" + x.baz + ")");
} else {
    console.log("x is not Baz must be FooBar : " + x.foo + "," + x.bar);
}

也编译好,但打印x is not Baz must be FooBar : foo,undefined

因此接受此类输入是一个错误,或者允许它导致instanceof类型后卫类型缩小的错误。