noImplicitThis
noImplicitThis
はthisの型注釈を必須にするコンパイラオプションです。
- デフォルト: strictが有効の場合は
true
、それ以外はfalse
- 追加されたバージョン: 2.0
- TypeScript公式が有効化推奨
解説
名前付き関数、匿名関数はアロー関数と異なり、実行時にthis
が決定されます。そのため、内部でthis
を使っているとそれらは関数を書いている時点ではany
型と同じ扱いになります。
たとえば、対角線の長さを求める関数lengthOfDiagonal()
を考えます。(横, 縦)を (width, height) とすれば関数は次のようになります。
ts
functionlengthOfDiagonal (): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}
ts
functionlengthOfDiagonal (): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}
これをwidth, height
をプロパティに持つオブジェクトのインスタンスに代入すれば対角線の長さを計算できます。
ts
constarea = {width : 3,height : 4,diagonal :lengthOfDiagonal ,};console .log (area .diagonal ());
ts
constarea = {width : 3,height : 4,diagonal :lengthOfDiagonal ,};console .log (area .diagonal ());
このとき、打ち間違いでwidth
をwitch
としてしまったとするとこの関数は意図した結果を返さなくなります。
ts
constarea = {witch : 3,height : 4,diagonal :lengthOfDiagonal ,};console .log (area .diagonal ());
ts
constarea = {witch : 3,height : 4,diagonal :lengthOfDiagonal ,};console .log (area .diagonal ());
このオプションを有効にするとany
型として認識されてしまっているthis
がどの型であるかを明確にできない限り実行することができなくなります。
ts
functionlengthOfDiagonal (): number {return ('this' implicitly has type 'any' because it does not have a type annotation.this .width ** 2 +this .height ** 2) ** (1 / 2);
'this' implicitly has type 'any' because it does not have a type annotation.2683
2683'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.}
ts
functionlengthOfDiagonal (): number {return ('this' implicitly has type 'any' because it does not have a type annotation.this .width ** 2 +this .height ** 2) ** (1 / 2);
'this' implicitly has type 'any' because it does not have a type annotation.2683
2683'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.}
これを回避するためにはthis
が何かを明示します。引数のthis
については関数のページに詳細がありますので併せてご参照ください。
📄️ this引数
アロー関数以外の関数とクラスのメソッドの第1引数はthisという特殊な引数を受けることができます。これは使用するコンテキストによってthisの意味するところが変わってしまうため、これらがどのコンテキストで使用されるべきなのかをTypeScriptに伝えるために使います。このthisは呼び出す側は意識する必要はありません。第2引数以降を指定してください。
ts
typeArea = {width : number;height : number;diagonal (): number;};functionlengthOfDiagonal (this :Area ): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}constarea :Area = {width : 3,height : 4,diagonal :lengthOfDiagonal ,};
ts
typeArea = {width : number;height : number;diagonal (): number;};functionlengthOfDiagonal (this :Area ): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}constarea :Area = {width : 3,height : 4,diagonal :lengthOfDiagonal ,};