microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.18k stars 12.51k forks source link

Another inference bug #3067

Closed zpdDG4gta8XKpMCd closed 9 years ago

zpdDG4gta8XKpMCd commented 9 years ago

Not sure if this one relates to #3038

interface A {
    x: string;
}

interface B {
    x: string;
    y: string;
}

function copyB(value: B): B {
    return undefined;
}

var values: A[] = [];

values.map(value => copyB(value)) // fails as expected
values.map(copyB); // <-- expected to fail, but it does not

Can seen at playground: link

ahejlsberg commented 9 years ago

That is by design. For purposes of assignment compatibility, parameters in signatures are bi-variant. We do this more by necessity than choice. There is good discussion of the issue in #1394. As @RyanCavanaugh points out in that thread, without this rule Array<Dog> wouldn't be a structural subtype of Array<Animal>.

zpdDG4gta8XKpMCd commented 9 years ago

@ahejlsberg, this is a very sad news to me, we are not using array methods (they are commented out in our lib.d.ts), is there a way to detect this pattern in code using compiler API?

danquirk commented 9 years ago

@aleksey-bykov See #274. It's definitely possible to change the compiler's behavior to disallow this, and we've considered it already as you can see in that issue. It would simply need to be opt in behavior or else it breaks too much existing code (including core JS idioms).