【TypeScript】メソッドのthisの扱い次第ではTypeScriptでエラー検知できない
メソッドでthisを用いる際にTypeScriptではエラー検知できない場合がある
コンパイルが通るが、実行時にエラーになるようなパターンが起こり得ます。
それについて記述していきます。
再現方法
class Car { name: string; gas: number; constructor(name: string, gas: number = 0) { this.name = name; } addGas(amount: number) { this.gas += amount; } } const car = new Car('PRIUS', 20); car.addGas(10); const copyCar = {addGas: car.addGas}; copyCar.addGas(20);
ここでは特にエラーを表す赤い波線は出ていません。
そのためコンパイルが通ります。
addGasメソッドを呼び出してみます。
copyCarにはgasプロパティが定義されていないからです。
メソッドでthisを用いている場合、
メソッドの前にあるオブジェクト内のプロパティやメソッドを指します。
car.addGas()だとcarオブジェクトのgasプロパティを参照し、
copyCar.addGas()だとcopyCarのgasプロパティを参照しようとします。
もちろん、copyCarにはgasプロパティは存在しない(undefined)ため
gasを追加することができずNaNになります。
対処方法
きちんとTypeScriptで検知するためには
メソッドの第1引数(※必ず第1引数にする)にthis: クラス名を入れます。
今回の例では下記のようにします。
addGas(this: Car, amount: number) { this.gas += amount; console.log(this.gas); }
そうすることできちんとエラーが出現します。
The 'this' context of type '{ addGas: (this: Car, amount: number) => void; }' is not assignable to method's 'this' of type 'Car'. Type '{ addGas: (this: Car, amount: number) => void; }' is missing the following properties from type 'Car': name, gas type '{ addGas: (this: Car, amount: number) => void; }' の 'this' コンテキストは、type 'Car' のメソッドの 'this' に代入できません。 タイプ '{ addGas: (this: Car, amount: number) => void; }' には、タイプ 'Car' の以下のプロパティがありません: name, gas
このことからわかるように、thisに対してCarクラスの型であることを明示してあげることでエラーを表示させることができるようになります。