Common sense suggests that subtyping should be covariant with respect to return type but contravariant with respect to argument types. So, the following should be rejected, because of the strictly covariant argument type of E.f
:
interface C {
f (o: C): void
}
interface D extends C {
g (): void // give D an extra service
}
class E implements C {
// implement f with a version which makes stronger assumptions
f (o: D): void {
o.g() // rely on the extra service promised by D
}
}
// E doesn't provide the service required, but E.f will accept
// an E argument as long as I invoke it via C.
var c: C = new E()
console.log('Try this: ' + c.f(c))
Indeed, running the program prints
Uncaught TypeError: o.g is not a function
So: (1) what's the rationale here (presumably there is one, however unsatisfying and JavaScripty); and (2) is there any practical reason why the compiler can't omit a warning in this situation?