Consider the following Typescript code:
class OrderFixture {
orderId: string;
constructor() {
this.orderId = "foo";
}
}
class DecisionFixture {
decisionId: string;
constructor() {
this.decisionId = "bar";
}
}
class FixtureStore {
order = () => new OrderFixture();
decision = () => new DecisionFixture();
}
const fixtureStore = new FixtureStore();
export function getFixture<
K extends keyof FixtureStore,
T extends ReturnType<FixtureStore[K]>
>(entityName: K): T {
return fixtureStore[entityName](); // ERROR: Type 'OrderFixture' is not assignable to type 'T'.
}
It yields the following type error:
Type 'OrderFixture | DecisionFixture' is not assignable to type 'T'.
'OrderFixture | DecisionFixture' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'OrderFixture | DecisionFixture'.
Type 'OrderFixture' is not assignable to type 'T'.
'OrderFixture' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'OrderFixture | DecisionFixture'.ts(2322)
Here is a playground.
There seems to be a fairly canonical answer to the question raised by this type of error but I am unable to see any relevant similarity between the two causes laid out there and my code.
If I force cast the return value to T
as suggested in this answer I get the right types when invoking getFixture
. Why doesn't Typescript infer these types for me?