接口类型推断

Interface type inference

我有以下类型:

interface A { a: string }
interface B extends A { b: string }
interface C extends A { c: string }

我现在想编写以下 return 一个 A 的函数:

function test(t: number): A {
    return t > 10
        ? { a: "a", b: "b" }
        : { a: "a", c: "c" };
}

这仅在我将 returned 对象显式转换为 ABC 时有效,或者如果我创建显式 [=29] 的单独函数=] BC 并使用它们构造对象。

编译器是否可以通过任何方式推断 returned 对象实际上是 BC,因此也是 A,无需我指定?

我的理解是,这是因为 TypeScript 对关于多余属性的对象字面量施加了额外的约束。如果重新写成这样就不会报错了:

interface A { a: string }
interface B extends A { b: string }

function test(): A {
    const result = { a: "a", b: "b" };
    return result;
}

还有suppressExcessPropertyErrorscompiler option.

看起来 TypeScript 不会将对象的类型推断为由接口定义的类型。

{ a: "a", b: "b" }的推断类型是{ a: string, b: string },可以在任何可以使用AB的地方使用,但它既不是A 也不是 B,是不同的类型。

所以答案是:不,编译器不会推断 AB,它会推断其他东西,如果所需类型是 A,则需要强制转换或 B.