Reputation: 495
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?
Upvotes: 1
Views: 120
Reputation: 276239
No. It should not be a compiler bug. You should be free to declare any signature you feel suitable for your class as long as it the type is compatible. e.g. void (as in your example) or any
as in below example :
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(param:any) { // is compatible
console.log("Derived1");
super.SomeMethod(parseInt(param,10));
}
}
works. However string
would give a compiler error:
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(param:string) { // not compatible, compiler error
console.log("Derived1");
super.SomeMethod(parseInt(param,10));
}
}
Upvotes: 1