网站搜索

typescript - 接口类型推断


我有以下类型:

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

我现在想编写以下函数,该函数返回一个 A:

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

这仅在我显式地将返回的对象转换为A、B或C时有效,或者当我创建单独的函数显式返回B或C并使用它们来构造对象时有效。

有没有办法让编译器推断出返回的对象实际上是一个 B 或 C,因此也是一个 A,而不需要我去指定?

答案#1

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

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

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

还有 suppressExcessPropertyErrors 编译器选项。

答案#2

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

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

所以答案是:不,编译器不会推断 A 或 B,它会推断其他类型,如果想要的类型是 A 或 B,则需要进行类型转换。