Description
I encountered a behavior of interface implementations which at first I taught was strange. Consider the following interfaces
interface IEventArgs {}
interface IDispatchable {
dispatch(type: string, args: IEventArgs): void;
}
Upon implementing this, I expected that typescript would force me to use a matching signature, but it accepts every signature which vaguely matches the implementation.
For example this will not raise an error
// expected
class A implements IDispatchable {
dispatch(type: string, args: IEventArgs): void {}
}
// according to typescript this is valid as well
class B implements IDispatchable {
dispatch(): number { return 1; }
}
If I think about it in terms of JavaScript it makes sense that it would accept B. Even though someone would give me N
arguments, the function can just ignore them. Moreover even though a function returns a number
we can still ignore them.
But from a OO design perspective this is strange (at least to me). The signature of B
's method dispatch
does not even come close to the expected signature.
Suggestion
Now this is a long shot, but maybe more people support this idea. What if we can mark a interface (or the interface method) as strict. Which would mean that it would only accept implementations with the exact same function signature.
For example
interface IEventArgs {}
strict interface IDispatchable {
dispatch(type: string, args: IEventArgs): void;
}
// good
class A implements IDispatchable {
dispatch(type: string, args: IEventArgs): void {}
}
// error
class B implements IDispatchable {
dispatch(): number { return 1; }
}
Another less elegant solution would be a config flag.
I actually don't have an idea if this is within the operation scope of typescript, but sharing ideas is never a bad thing to do. And maybe the makes of typescript have considered this already and made a specific design decisions, in that case I am curious why.