Consider a TypeScript interface with two implementations:
interface IFoo {}
class FooA implements IFoo {}
class FooB implements IFoo {}
Next, consider a generic interface that accepts an implementation of IFoo as type parameter:
interface IFooHandler<F extends IFoo> {
handle(foo: F): string
}
Now, let's implement the IFooHandler interface with a specific implementation of IFoo as a type parameter:
class FooAHandler implements IFooHandler<FooA> {
handle(foo: FooB): string {
return "Hello, Foo A!";
}
}
This compiles perfectly, using tsc in version 2.0.3. So here's my question: Why does this compile?
Note that I've used FooB as parameter type in the FooAHandler's handle() function. I would assume that this code would trigger a compiler error, as the IFooHandler<F> interface prescribes that the handle method should accept a parameter of type F (so, in case of a IFooHandler<FooA>, of type FooA -- and not FooB).
I could not find anything on this behaviour in the TypeScript documentation. Is this behaviour intentional, and if so, what's the reasoning behind it? Or am I just using this feature the wrong way?
Just for comparison, implementing the exact same example in Java (omitting the code, as it's quite similar) yields the (expected) compile error:
FooAHandler.java:1: error FooAHandler is not abstract and does not override abstract method handle(FooA) in IFooHandler