AccessViolation Exception

仕事でもはんだづけ、家でもはんだづけ

TypeScriptで拡張メソッドを実現する

タイトルで違和感を感じれば多分正しくjavascrptを理解してる。

自分も調べていて気付いた。

c sharp

static class Extension {
    public static void Hoge(this string str){ 
         Console.WriteLine(str);
    }
}
//"foo".Hoge()

みたいなやつ。これでstringの拡張メソッドが実現するわけだが、javascriptなんてそもそもがprototypeに勝手にバンバン定義していくだけのものだと理解すべきであって

javascript

String.prototype.hoge = function(){
    console.log("Hoge!")
}

"foo".hoge();

これが当たり前。むしろこれ以外の手段は知らない。TypeScriptに汚染されてここらの概念すら忘れていたがおかげて少し理解が深まった。

本題


残念ながら上のjavascriptと同じようなコードをTypeScriptでやってもエラーになる。

proto.ts(2,18): error TS2094: The property 'hoge' does not exist on value of type 'String'.
proto.ts(6,7): error TS2094: The property 'hoge' does not exist on value of type 'string'.

当然である。定義されてないものが使えたらもはやTypeScriptの存在意義すら怪しい。

解決


ところでWebページ作っている時も思ったがinterfaceはコンパイルする段階で消滅して、いわば実装側に[Interface Name].prototype.XXXXの部分を提供しているだけだということに気づく。

interface、もしかして名前の重複とか関係ないのでは?と気づいたのが幸いだった。

TypeScript

interface String {
    hoge();
}
String.prototype.hoge = () => {
    console.log("Hoge!");
};

"foo".hoge;

吐出されるコードはjavascriptで書いたコードと全く同じだった。ちなみにinterfaceだけだとコンパイルすると何も残らない*1

*1:TypeScriptのコンパイルは最適化されない