精炼打字稿不相交联合

Refining typescript disjoint union

我正在尝试让类似下面的东西工作,但是打字稿在尝试访问 o.foo 属性:

时输出错误
type Base = { s: string };
type Extra = { foo: string; };
type Other = { bar: string; };
type T = Base & (Extra | Other);

function f(o: T): string {
    if (typeof o.foo === 'string') {
        return o.s + o.foo;
    }
    return o.s + o.bar;
}

错误是

Property 'foo' does not exist on type 'T'.
  Property 'foo' does not exist on type 'Base & Other'.

似乎 typescript 无法正确推断如果 o 有一个 foo 属性,那是一个字符串,那么 o 的类型必须是在工会的 Base & Extra 分支中。

有什么办法让它理解这个吗?

您无法访问联合成员,除非他们是普通成员。您可以改用 in typeguard:

type Base = { s: string };
type Extra = { foo: string; };
type Other = { bar: string; };
type T = Base & (Extra | Other);

function f(o: T): string {
    if ('foo' in o) {
        return o.s + o.foo;
    }
    return o.s + o.bar;
}