TypeScript Version: tested with 3.5, 3.6, next
Search Terms:
typescript allows assigning incompatible types
typescript allows assigning generic interfaces without full overlap
Code
type Entity = { id: string };
type Participant = Entity & { participantName: string };
type Trainer = Entity & { trainerName: string };
type Master = Trainer & { masterName: string };
interface EntityRepository<T extends Entity> {
load<U extends T = T>(id: string): Promise<U>;
}
// should not work as Participant doesn't extend Trainer
const a: EntityRepository<Trainer> = (null as any) as EntityRepository<Participant>;
// doesn't work as expected, as Participant doesn't extend Trainer
a.load<Participant>("");
// works as expected, as Master extends Trainer
a.load<Master>("");
Expected behavior:
Assigning EntityRepository<Participant> to EntityRepository<Trainer> should raise an error, as Participant is not assignable to Trainer.
Actual behavior:
Typescript does not complain at all for the assignation.
Extra note:
If I remove U extends T = T from load and return Promise<T> instead of Promise<U> everything works as expected.
A workaround I found for myself is adding a fake property _type: T to the interface.
Playground Link:
Playground
Related Issues:
#31006
TypeScript Version: tested with 3.5, 3.6, next
Search Terms:
typescript allows assigning incompatible types
typescript allows assigning generic interfaces without full overlap
Code
Expected behavior:
Assigning
EntityRepository<Participant>toEntityRepository<Trainer>should raise an error, asParticipantis not assignable toTrainer.Actual behavior:
Typescript does not complain at all for the assignation.
Extra note:
If I remove
U extends T = Tfromloadand returnPromise<T>instead ofPromise<U>everything works as expected.A workaround I found for myself is adding a fake property
_type: Tto the interface.Playground Link:
Playground
Related Issues:
#31006