Closed
Description
TypeScript Version:
1.9.0-dev.20160405
Code
class Animal {
name: string;
}
class Dog extends Animal {
bark() {};
}
class Cat extends Animal {
meow() {};
}
class Box<V> {
item: V;
}
function f<T extends Box<Animal>>(box: T) {
box.item = new Cat(); // <-- This is perfectly valid and allowed by the constraint
return box; // <-- The returned type is T
}
let result = f(new Box<Dog>()); // Type of 'result' is inferred as Box<Dog>
result.item.bark(); // <-- No compilation error. Run-time error..
Expected behavior:
Type of result
should be inferred as Box<Animal>
.
result.item.bark();
should give a compilation error.
Actual behavior:
Type of result
is inferred as Box<Dog>
.
result.item.bark();
does not error at compile-time but does error at run-time.
Comments:
Type of box
should be widened from T
to Box<Animal>
within the body of the function, as there is no (current) way to ensure the members of box
are not reassigned with types incompatible to the ones specified in T
. The return type should therefore be Box<Animal>
and not T
.
[Edits: rewritten main example, heavily shortened and removed unneeded sections]