TypeScriptで「'this' 暗黙的に 'any' 型を持っています」エラーの原因と解決策
TypeScriptで「'this' 暗黙的に 'any' 型を持っています」エラーの原因と解決策
TypeScriptでthis
キーワードを使用する際に、「'this' 暗黙的に 'any' 型を持っています」というエラーが発生することがあります。これは、this
の型が正しく推論できない場合に発生するエラーです。
原因
このエラーが発生する主な原因は以下の2つです。
-
thisの型が推論できない
解決策
このエラーを解決するには、以下の方法があります。
class MyClass {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): string {
return this.name; // thisはMyClass型
}
}
tsc --noImplicitAny my-file.ts
const myFunction = function(this: MyClass) {
// thisはMyClass型
}.bind(new MyClass('John Doe'));
補足
this
キーワードは、現在のオブジェクトへの参照を表します。any
型は、どんな型でも代入できる型です。- 型推論は、コンパイラが変数や関数の型を自動的に推測する機能です。
上記以外にも、this
の型に関する様々な問題があります。詳細は、上記の参考資料などを参照してください。
// サンプルコード
// 1. `this`の型が推論できない
function myFunction(name: string) {
console.log(this.name); // エラー: 'this' 暗黙的に 'any' 型を持っています
}
myFunction('John Doe');
// 2. `this`の型が正しく推論されない
class MyClass {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): string {
const myFunction = function() {
console.log(this.name); // エラー: 'this' 暗黙的に 'any' 型を持っています
};
myFunction();
return this.name;
}
}
const myClass = new MyClass('John Doe');
myClass.getName();
// 3. `--noImplicitAny`オプションを使用する
// tsc --noImplicitAny my-file.ts
function myFunction(name: string) {
console.log(this.name); // エラー: 'this' 型が不明です
}
myFunction('John Doe');
// 4. `this`のスコープを明確にする
const myFunction = function(this: MyClass) {
console.log(this.name); // エラー: 'this' 型が不明です
}.bind(new MyClass('John Doe'));
myFunction();
解説
実行方法
上記のコマンドをターミナルで実行することで、サンプルコードを実行することができます。
tsc my-file.ts
node my-file.js
出力結果
エラー: 'this' 暗黙的に 'any' 型を持っています
エラー: 'this' 型が不明です
エラー: 'this' 型が不明です
thisの型を推論するためのその他の方法
ジェネリック型を使用することで、this
の型をパラメータとして指定することができます。
class MyClass<T> {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): T {
return this.name as T; // thisはMyClass<T>型
}
}
const myClass = new MyClass('John Doe');
const name = myClass.getName(); // nameはstring型
type MyClass = {
name: string;
getName(): string;
};
const myClass: MyClass = {
name: 'John Doe',
getName(): string {
return this.name; // thisはMyClass型
},
};
const name = myClass.getName(); // nameはstring型
class MyClass {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): string {
return (this as MyClass).name; // thisはMyClass型
}
}
const myClass = new MyClass('John Doe');
const name = myClass.getName(); // nameはstring型
this
キーワードは省略可能であり、省略するとthis
は現在のスコープのオブジェクトを指します。
class MyClass {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): string {
return name; // thisはMyClass型
}
}
const myClass = new MyClass('John Doe');
const name = myClass.getName(); // nameはstring型
注意
上記の方法は、状況によっては適切でない場合があります。どの方法を使用するかは、コードの状況に合わせて判断する必要があります。
typescript typescript2.0