Reputation: 63442
I have the following types:
interface A { a: string }
interface B extends A { b: string }
interface C extends A { c: string }
I now want to write the following function that returns an A
:
function test(t: number): A {
return t > 10
? { a: "a", b: "b" }
: { a: "a", c: "c" };
}
This only works if I explicitly cast the returned objects to A
, B
or C
, or if I create separate functions that explicitly return either a B
or a C
and use these to construct the object.
Is there any way the compiler can infer that the returned object is, in fact, a B
or a C
and therefore also an A
, without me having to specify that?
Upvotes: 2
Views: 216
Reputation: 63442
Looks like TypeScript does not infer the type of an object to be that defined by an interface.
The inferred type of { a: "a", b: "b" }
is { a: string, b: string }
, which can be used wherever an A
or a B
can be used, but it's neither A
nor B
, it's a different type.
So the answer is: no, the compiler will not infer A
or B
, it will infer something else, and a cast is necessary if the desired type is A
or B
.
Upvotes: 0
Reputation: 58400
My understanding is that it's because TypeScript enforces additional constraints upon object literals regarding excess properties. If it's re-written like this, there is no error:
interface A { a: string }
interface B extends A { b: string }
function test(): A {
const result = { a: "a", b: "b" };
return result;
}
There is also the suppressExcessPropertyErrors
compiler option.
Upvotes: 1