I'm grappling with a concept that seems obvious to me, yet is disallowed by Typescript when all strict flags are enabled (presumably for valid reasons). Let me illustrate:
We all understand the following:
export interface Basic {
value: "foo" | "bar" | "baz";
}
export interface Constraint extends Basic {
value: "foo";
}
It works as expected. However, something more surprising (at least to me) is:
export interface WithFunctionsBasic {
value: (t: "foo" | "bar" | "baz") => void;
}
export interface WithFunctionsConstraint extends WithFunctionsBasic { // Incorrectly extends WithFunctionsBasic
value: (t: "foo") => void;
}
This does not work.
We can introduce generics to achieve this kind of behavior like so:
export interface WithFunctionsParametric<T extends Basic> {
value: (t: T["value""]) => void;
}
const variableConstraint: WithFunctionsParametric<Constraint> = { value: (t: "foo") => {} };
const variableBasic: WithFunctionsParametric<Basic> = { value: (t: "foo" | "bar" | "baz") => {} };
Both of these examples work. But it becomes slightly complicated because despite Constraint extending Basic:
const variableConstraint: WithFunctionsParametric<Constraint> = { value: (t: "foo") => {} };
const variableBasic: WithFunctionsParametric<Basic> = variableConstraint; // Does not work
In my understanding, if Constraint extends Basic (which it does), the latter should work. Can someone please explain why this isn't the case?