angularJsNewbie
angularJsNewbie

Reputation: 495

Typescript - isn't this a compiler bug?

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

Answers (1)

basarat
basarat

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

Related Questions