TypeScriptで次のコードをコンパイルすると「TS1184: Modifiers cannot appear here.」というエラーが出ました。最も可能性の高い原因はどれですか? function greet(public name: string) { console.log('Hello, ' + name); }
解説
正解は「アクセス修飾子はクラスのコンストラクタ引数でのみ使用できるため」です。TS1184 は、本来書いてはいけない場所に public / private / protected / readonly といった修飾子(modifier)が登場したときに出るエラーです。通常の関数の引数にこれらを付けることはできず、コンパイラは「ここにmodifierは書けないよ」と教えてくれています。public は TypeScript では厳密には予約語ではなく特定文脈でのみ意味を持つキーワードなので選択肢1は誤り、readonly 必須というルールも存在せず(選択肢3が誤り)、strict オプションとも無関係です(選択肢4が誤り、これは構文エラーなので strict の設定以前に常に発生します)。なぜコンストラクタ引数だけ特別扱いなのかTypeScript にはパラメータプロパティ(Parameter Properties)という便利な構文があります。クラスのコンストラクタ引数に public などの修飾子を付けると、「引数を受け取る」と「同名のプロパティとして代入する」を1行でまとめて書けるのです。// パラメータプロパティを使った書き方 class User { constructor(public name: string, private age: number) {} } // これは次のコードと等価 class User { public name: string; private age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }つまり修飾子は「このプロパティをどう公開するか」を宣言するもので、クラスの外側にある普通の関数では意味を持ちません。だからコンパイラが構文レベルで弾くわけです。TS1184が出やすい典型パターン関数をクラスメソッドに変換し忘れたケース: クラス内のメソッドのつもりで public を付けたが、実はトップレベル関数だったコピペ事故: クラスのコンストラクタから関数に引数定義だけコピーしてきたアロー関数に修飾子を付けたケース: const fn = (public x: number) => x のような書き方はできません。パラメータプロパティはあくまで constructor 専用ですエラーコードを調べる習慣をつけようTypeScriptのエラーメッセージは「TS + 数字」の形式で、エラーコードでググると原因にたどり着きやすいのがポイントです。メッセージの英文だけ見ると意味が取りにくい場合でも、コード番号は一意なので GitHub の issue や Stack Overflow で同じ状況の事例が見つかります。TS2322(型の不一致)、TS2304(名前が見つからない)、TS7006(暗黙のany)など頻出コードを覚えておくと、エラーを見た瞬間に原因の見当がつくようになり、デバッグ速度が一段上がります。