While learning Typescript, I stumbled upon this example somewhere on the web. I was surpised to see that this actually compiles:
class Base {
constructor (public name) { }
SomeMethod(param:number) {
console.log(this.name + " " + " called with param:" + param);
}
}
class Derived1 extends Base {
constructor(name) { super(name); }
SomeMethod() {
console.log("Derived1");
super.SomeMethod(2);
}
}
class Derived2 extends Base {
constructor(name) { super(name); }
SomeMethod() {
console.log("Derived2");
super.SomeMethod(4);
}
}
var one = new Derived1("one")
var two:Base = new Derived2("two")
one.SomeMethod()
two.SomeMethod(34)
The code is from a blog post I found, and I saw that (probably by mistake) the author changed the signature of "SomeMethod" in the derived classes to something that doesn't take an argument. He then instantiated two objects, one of type "Derived1" and one of "Derived2". In the first case, he used var to automatically make "one" be of type Derived1. In the second case, however, he declared it via var two:Base = ... - so he used a "pointer to base" to access it.
And since the base class has a "SomeMethod" prototype that does, in fact, take an argument, the call two.SomeMethod(34) actually passes from compilation, but at runtime, calls the Derived2 version:
Derived1
one called with param:2
Derived2
two called with param:4
Is this not a bug? Shouldn't the typescript compiler catch this case?