はじめに
「ESLintを導入しているのに、anyの握りつぶしやPromiseの投げっぱなしがレビューまで見つからない」——TypeScriptプロジェクトでこうしたすり抜けを経験したことはないでしょうか。
素のESLintは構文木(AST)だけを見てコードを検査します。そのため、変数がどんな型を持っているか、関数の戻り値が本当にawaitされているかといった、TypeScriptコンパイラだけが知っている情報までは踏み込めません。この壁を取り払うのが「typescript-eslint」です。TypeScriptのASTと型情報をESLintに橋渡しし、型を前提にしたルールでコードを検査できるようにします。
本記事では、typescript-eslintがなぜ必要なのか、どうインストールしてどう設定するのか、そして実際にどんなルールで型情報を活かせるのかを解説します。
typescript-eslintとは
typescript-eslintは、TypeScriptのコードをESLintで解析・検査するためのツールチェーンです。TypeScriptの構文をESLintが理解できるASTに変換する「パーサー」、TypeScript向けのルール集を提供する「プラグイン」、そしてこれらをまとめて設定できる「typescript-eslint」パッケージの3つで構成されています。以前は@typescript-eslint/parserと@typescript-eslint/eslint-pluginを別々にインストールして組み合わせる必要がありましたが、現在はメタパッケージのtypescript-eslintを使うことで、設定用のヘルパーごと一括で導入できます。
主な特徴
- TypeScript構文の完全なサポート - ジェネリクスやデコレータ、型注釈など、素のESLintパーサーでは構文エラーになるTypeScript特有の記法を正しく解析します
- 型情報を使った検査(Type-Aware Linting) -
strict-boolean-expressionsやno-floating-promisesのように、TypeScriptコンパイラの型チェック結果を前提にしたルールを適用できます - 段階的に強くできるルールセット -
recommended・strict・stylisticの3系統に加え、それぞれ型情報を使う-type-checked版が用意されており、プロジェクトの成熟度に合わせて選べます tseslint.config()ヘルパー - Flat Config(eslint.config.js)向けに、設定のマージや型補完を助けるユーティリティが標準で提供されています- モノレポ対応 -
projectServiceオプションにより、複数のtsconfig.jsonを持つワークスペースでも型情報の解決を自動化できます
インストール
npmを使う場合は、以下のコマンドでESLint本体とあわせて導入します。
npm install --save-dev eslint typescript typescript-eslint
pnpmやyarnを使っている場合は、それぞれ以下のように置き換えてください。
# pnpm
pnpm add -D eslint typescript typescript-eslint
# yarn
yarn add -D eslint typescript typescript-eslint
基本的な使い方
まずはプロジェクトルートのeslint.config.js(Flat Config)で、tseslint.config()を使って設定を組み立てます。
// eslint.config.js
import tseslint from "typescript-eslint";
export default tseslint.config(
tseslint.configs.recommended,
{
files: ["**/*.ts", "**/*.tsx"],
rules: {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "error",
},
}
);
設定ができたら、対象ファイルを指定して実行します。
npx eslint src/
ここまではJavaScriptのAST解析だけで完結する範囲です。次の章では、型情報を使ったより強力なチェックに踏み込みます。
実践的なユースケース
型情報を使ったルールを有効化する
recommendedは構文レベルのチェックにとどまりますが、recommendedTypeCheckedを使うと、TypeScriptコンパイラの型チェック結果を踏まえたルールが有効になります。たとえばno-floating-promisesは、awaitし忘れたPromiseや、意図せず無視されたエラーハンドリングを検出できます。型情報を使うにはlanguageOptions.parserOptions.projectServiceを有効にし、パーサーにtsconfig.jsonを参照させる必要があります。
// eslint.config.js
import tseslint from "typescript-eslint";
export default tseslint.config(
tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-unsafe-assignment": "warn",
},
}
);
こうしておくと、以下のようなコードはコンパイルこそ通っても、ESLint上で警告・エラーとして検出されるようになります。
async function fetchUser(id: string) {
return db.users.findOne({ id });
}
// awaitし忘れ → no-floating-promisesが検出
fetchUser("1");
// any由来の値をそのまま代入 → no-unsafe-assignmentが検出
const user: { name: string } = JSON.parse(rawJson);
型チェックを伴うルールはファイルごとに型情報の解決が走るため、素のESLintより実行に時間がかかります。CIではキャッシュ(--cache)を併用するとよいでしょう。
モノレポでのプロジェクトサービス設定
パッケージごとにtsconfig.jsonが分かれているモノレポでは、どのファイルがどのtsconfig.jsonに属するかをESLintに教える必要があります。projectServiceを有効にすると、typescript-eslintがワークスペース内のtsconfig.jsonを自動的に探索し、ファイルごとに適切な設定を割り当ててくれます。
// eslint.config.js(モノレポのルート)
import tseslint from "typescript-eslint";
export default tseslint.config(
tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: {
allowDefaultProject: ["*.config.ts"],
},
tsconfigRootDir: import.meta.dirname,
},
},
}
);
allowDefaultProjectに対象パターンを指定すると、どのtsconfig.jsonにも含まれない設定ファイル(例: eslint.config.ts自身)についても、専用のデフォルトプロジェクトでフォールバック解決してくれるため、「このファイルはどのtsconfigにも属していません」といったエラーを避けられます。
厳格度に応じたルールセットの切り替え
typescript-eslintはrecommendedより厳しいstrict、コードスタイルに特化したstylisticという系統も提供しています。新規プロジェクトでは最初からstrictを採用し、既存の大規模プロジェクトへ後から導入する場合はrecommendedから始めて段階的に引き上げる、という使い分けが一般的です。
// eslint.config.js
import tseslint from "typescript-eslint";
export default tseslint.config(
// 新規プロジェクト向け: 型チェックも含めた厳格な構成
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
rules: {
// チームの合意に応じて個別に緩めることもできる
"@typescript-eslint/no-non-null-assertion": "off",
},
}
);
strictTypeCheckedはno-unsafe-argumentやno-non-null-assertionなど、anyの混入や非nullアサーションの濫用を厳しく検出します。既存コードにいきなり適用すると警告が大量に出ることが多いため、--fixで自動修正できるものから解消しつつ、残りは// eslint-disable-next-lineで理由付きで許容していくのが現実的です。
まとめ
typescript-eslintは、TypeScriptの構文を正しく解析するだけでなく、型情報を武器にしてESLintを一段階賢くしてくれるツールチェーンです。recommendedからstrictTypeCheckedまで段階的に選べるルールセットと、モノレポにも対応したprojectServiceによって、プロジェクトの規模やフェーズに合わせた導入がしやすくなっています。
すでにESLintを使っているTypeScriptプロジェクトであれば、まずはrecommendedTypeCheckedを有効にして、型チェックだけが見つけられるバグをどれだけ拾えるか試してみてはいかがでしょうか。