Typescript を学習しているときに、Web 上のどこかでこの例を見つけました。これが実際にコンパイルされるのを見て驚いた:
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)
このコードは、私が見つけたブログ投稿からのもので、(おそらく誤って) 作成者が派生クラスの "SomeMethod" の署名を引数を取らないものに変更したことがわかりました。次に、「Derived1」タイプと「Derived2」タイプの 2 つのオブジェクトをインスタンス化しました。最初のケースでは、彼はvar
自動的に "one" を type にしてDerived1
いました。ただし、2 番目のケースでは、彼はそれを経由で宣言したvar two:Base = ...
ため、「ベースへのポインター」を使用してアクセスしました。
基本クラスには、実際には引数を取る "SomeMethod" プロトタイプがあるため、呼び出しtwo.SomeMethod(34)
は実際にはコンパイルから渡されますが、実行時に Derived2 バージョンを呼び出します。
Derived1
one called with param:2
Derived2
two called with param:4
これはバグではありませんか?typescript コンパイラはこのケースをキャッチすべきではありませんか?