Reputation: 3583
I'm wondering why implementing twice same generic interface but with different parameters doesn't enforce the correct signatures in the derived class. The type of the generic parameter is omitted.
Please see sample:
interface IEvent { id: number; }
interface IHandle<T> {
handle(event: T): void;
}
class EmailSentEvent implements IEvent {
constructor(public id: number, public address: string) {}
}
class UserRegisteredEvent implements IEvent {
constructor(public id: number) {}
}
class MailHandlerState implements
IHandle<EmailSentEvent>,
IHandle<UserRegisteredEvent>
{
// One implementation is enough to satisfy both interfaces
handle = (event: EmailSentEvent): void => {
};
}
Is there a way to enforce the implementation of both generic parameters? Thank you!
Upvotes: 4
Views: 1034
Reputation: 37928
TLDR:
To make this work, change method notation
interface IHandle<T> {
handle(event: T): void;
}
to property with a function type
interface IHandle<T> {
handle: (event: T) => void;
}
** In this specific case implementation can still use method syntax
Turns out this works as intended:
--strictFunctionTypes
mode in which function type parameter positions are checked contravariantly instead of bivariantly. The stricter checking applies to all function types, except those originating in method or construcor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array) continue to mostly relate covariantly. The impact of strictly checking methods would be a much bigger breaking change as a large number of generic types would become invariant (even so, we may continue to explore this stricter mode)
Also in handbook
Upvotes: 2