ESLint コアルールの TypeScript 対応について
ESLint コアルールの TypeScript 対応について
ESLint v9.23.0 で ESLint のコアルールの TypeScript 対応が開始しました。
その後の ESLint のアップデートでもコアルールの TS 対応が進んでいます。ESLint コアの責務を増やすような機能追加は少し意外だと感じたので、その背景について調べてみました。
背景: 従来のコアルールの拡張方法の課題
ESLint のコアルールは JavaScript を想定して書かれたものであるが、TypeScript に対してもほぼ期待通り動作するルールが多い。TypeScript は JS のほぼ上位互換な言語であるため、TypeScript 用のパーサー (@typescript-eslint/parser
) が吐き出す AST もほぼ JS の上位互換であり、パーサーさえ TS 用のものを使えば多くの ESLint コアルールを TS に対しても使うことができる。
しかし、一部のコアルールはそのままの挙動では TS では満足できないケースがあるため、@typescript-eslint
プラグインでコアルールの拡張も行ってきた。プラグイン側で TS 特有の事情に合わせて挙動を修正したり、オプションを追加したりしている。しかし、その実装においては、コアルールを外から力技で拡張するような方式になっていた。
例えば no-unused-expressions
は、TS 版の@typescript-eslint/no-unused-expressions
では TS 特有の型キャスト構文 x as number;
を考慮するように拡張されている。その実装を見ると、コアルールの挙動と内部実装を前提に拡張していることがわかる。
そんな中、ESLint v9.15.0 のリリースで問題が発生した。
- Bug: Error while loading rule '@typescript-eslint/no-unused-expressions'
- typescript-eslint issue #10338
ESLint コアルールの内部実装の変更により、@typescript-eslint
プラグイン側で拡張していた部分が動かなくなった。
これに対して ESLint チームは、プラグイン開発者がコアルールの内部実装に依存することは推奨されないと正式に表明した。
以下の方針が決まり、ドキュメントにも反映された。
- コアルールは公開 API の一部ではない
- ルールは ESLint 自体以外からロードすべきではない
- ルールは予告なく変更または削除される可能性がある
- プラグインがコアルールを拡張したい場合、ルールのファイルをプラグインのプロジェクトにコピーして独自に実装すること
対応: ESLint コアルールで TypeScript 対応することに
上記の方針は至極真っ当であるものの、プラグイン開発者のメンテナンス負担を増やす内容でもある。そこで @typescript-eslint
プラグインのメンテナは、対策がないか議論を開始した。
議論の中で、ESLint としてはコアルールの拡張はさせないということが改めて確認されたが、一方でコアルールを TS にも対応する方針が示された。
ESLint コアルールのうち、構文レベルで TS も検証可能なものは ESLint コアルールで TS 対応する方針となった。一方で、TS の型情報を必要とするルールや TS 固有のコンテキストに関連するルールは、引き続き @typescript-eslint
プラグインで対応していくことになっている。
また対応言語がわかるように、ルールのメタデータに meta.language
と meta.dialects
を追加することも決まった。
例えば以下の no-empty-function
の TS 対応を見ると、TS 用のオプションを @typescript-eslint
プラグインから ESLint コアに移植しつつ、TS用のテストコードもガッツリ書いていることが分かる。
コアチームがそのような決定をした背景として、以下の discussion が参考になる。従来から、ここまで一般化した TypeScript での ESLint 利用が、プラグイン依存で標準ではできないということに対しては問題意識があったようだ。
今後も対応するルールを増やしていき、全て移行したところで @typescript-eslint
プラグイン側の拡張ルールが非推奨になり、次期メジャーアップデートでの recommended の修正と非推奨ルールの削除で一連の取り組みが完了、という流れで進んでいくことが予想される。
感想
今回の ESLint のコアルールの TypeScript 対応は、単なる機能追加というよりも、プラグインエコシステムをどう設計するかという要素が大きいと言えるでしょう。昨今の TypeScript の流行も踏まえれば妥当な落とし所かもしれません。
ところでこの記事は、Cursor と VS Code (GitHub Copilot) の AI アシストを使って調査と執筆をしてみる練習として書いてみました。まだまだもどかしい動きが多いです。
Discussion