noImplicitThis
リリースされたバージョン: 2.0
名前付き関数、匿名関数はアロー関数と異なり、実行時にthisが決定されます。そのため、内部でthisを使っているとそれらは関数を書いている時点ではany型と同じ扱いになります。
たとえば、対角線の長さを求める関数 lengthOfDiagonal() を考えます。(横, 縦)を (width, height) とすれば関数は次のようになります。
typescriptfunction lengthOfDiagonal(): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}
typescriptfunction lengthOfDiagonal(): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}
これを width, height をプロパティに持つオブジェクトのインスタンスに代入すれば対角線の長さを計算できます。
typescriptconst area = {width: 3,height: 4,diagonal: lengthOfDiagonal,};console.log(area.diagonal());// -> 5
typescriptconst area = {width: 3,height: 4,diagonal: lengthOfDiagonal,};console.log(area.diagonal());// -> 5
このとき、打ち間違いで width を witch としてしまったとするとこの関数は意図した結果を返さなくなります。
typescriptconst area = {witch: 3,height: 4,diagonal: lengthOfDiagonal,};console.log(area.diagonal());// -> NaN
typescriptconst area = {witch: 3,height: 4,diagonal: lengthOfDiagonal,};console.log(area.diagonal());// -> NaN
このオプションを有効にすると any 型として認識されてしまっている this がどの型であるかを明確にできない限り実行することができなくなります。
texterror TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. return ((this.width ** 2) + (this.height ** 2)) ** (1/2); ~~~~ error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. return ((this.width ** 2) + (this.height ** 2)) ** (1/2); ~~~~
texterror TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. return ((this.width ** 2) + (this.height ** 2)) ** (1/2); ~~~~ error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. return ((this.width ** 2) + (this.height ** 2)) ** (1/2); ~~~~
これを回避するためには thisが何かを明示します。引数のthisについては関数のページに詳細がありますので併せてご参照ください。
typescripttype Area = {width: number;height: number;diagonal(): number;};function lengthOfDiagonal(this: Area): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}const area: Area = {width: 3,height: 4,diagonal: lengthOfDiagonal,};
typescripttype Area = {width: number;height: number;diagonal(): number;};function lengthOfDiagonal(this: Area): number {return (this.width ** 2 + this.height ** 2) ** (1 / 2);}const area: Area = {width: 3,height: 4,diagonal: lengthOfDiagonal,};