TypeScript: subtyping and covariant argument types
<p>Common sense suggests that subtyping should be covariant with respect to return type but <strong>contravariant</strong> with respect to argument types. So, the following should be rejected, because of the strictly covariant argument type of <code>E.f</code>:</p>

<pre><code>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))
</code></pre>

<p>Indeed, running the program prints</p>

<pre><code>Uncaught TypeError: o.g is not a function
</code></pre>

<p>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?</p>