はじめに#
TypeScriptプロジェクトでコード品質を維持するには、静的解析ツールのESLintとコードフォーマッターのPrettierの適切な設定が不可欠です。本記事では、typescript-eslintを使用したESLintのセットアップから、Prettierとの統合、型情報を活用した高度なLintingまで、TypeScriptプロジェクトのコード品質管理を体系的に解説します。
ESLint 9以降で導入されたFlat Config形式を採用し、2026年現在の最新のベストプラクティスに基づいた設定方法を紹介します。
本記事を読むことで、以下のことができるようになります。
- TypeScriptプロジェクトにtypescript-eslintを正しくセットアップする
- 推奨ルールセット(recommended、strict、strictTypeChecked)を理解し適切に選択する
- ESLintとPrettierを競合なく統合する
- 型情報を活用した高度なLintingを設定する
- チーム開発で一貫したコードスタイルを維持する
実行環境・前提条件#
前提知識#
- TypeScriptの基本的な知識
- Node.jsとnpmの基本的な使い方
- コマンドラインの基本操作
動作確認環境#
本記事の内容は、以下の環境で動作確認を行っています。
| ソフトウェア |
バージョン |
| Node.js |
22.x LTS |
| npm |
10.x 以上 |
| TypeScript |
5.7 以上 |
| ESLint |
9.x 以上 |
| typescript-eslint |
8.x 以上 |
| Prettier |
3.x 以上 |
期待される結果#
本記事の手順を完了すると、以下の状態になります。
- ESLintによるTypeScriptコードの静的解析が動作する
- Prettierによる自動コードフォーマットが動作する
- ESLintとPrettierが競合せずに共存する
- 型情報を活用した高度なLintingルールが適用される
ESLintとPrettierの役割分担#
TypeScriptプロジェクトでコード品質を管理する際、ESLintとPrettierは異なる役割を担います。
graph LR
subgraph "コード品質ツール"
A[ESLint] --> B["コード品質チェック<br/>バグの検出<br/>ベストプラクティスの強制"]
C[Prettier] --> D["コードフォーマット<br/>インデント・スペース<br/>改行・クォート"]
end
B --> E[高品質なTypeScriptコード]
D --> E
| ツール |
役割 |
例 |
| ESLint |
コード品質・ロジックのチェック |
未使用変数の検出、型安全でない操作の警告 |
| Prettier |
コードの見た目の統一 |
インデント、セミコロン、クォートスタイル |
この役割分担を明確にすることで、両ツールの競合を避け、効率的なコード品質管理が可能になります。
typescript-eslintのセットアップ#
必要なパッケージのインストール#
TypeScriptプロジェクトでESLintを使用するには、typescript-eslintパッケージが必要です。以下のコマンドで必要なパッケージをインストールします。
1
|
npm install --save-dev eslint @eslint/js typescript typescript-eslint
|
各パッケージの役割は以下の通りです。
| パッケージ |
役割 |
eslint |
ESLint本体 |
@eslint/js |
ESLintのJavaScript向け推奨ルール |
typescript |
TypeScriptコンパイラ |
typescript-eslint |
TypeScript向けESLintプラグイン・パーサー・設定の統合パッケージ |
ESLint設定ファイルの作成#
プロジェクトルートにeslint.config.mjsファイルを作成します。ESLint 9以降では、Flat Config形式が標準となっています。
1
2
3
4
5
6
7
8
9
10
|
// eslint.config.mjs
// @ts-check
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommended
);
|
この設定により、以下のルールが有効になります。
- ESLintの推奨ルール(
eslint.configs.recommended)
- typescript-eslintの推奨ルール(
tseslint.configs.recommended)
ESLintの実行#
設定が完了したら、ESLintを実行してコードをチェックします。
特定のディレクトリやファイルを対象にする場合は、パスを指定します。
1
2
3
4
5
|
# srcディレクトリのみチェック
npx eslint src/
# 特定のファイルをチェック
npx eslint src/index.ts
|
package.jsonにスクリプトを追加#
ESLintの実行を簡単にするため、package.jsonにスクリプトを追加します。
1
2
3
4
5
6
|
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}
|
typescript-eslintの推奨ルールセット#
typescript-eslintは複数の推奨ルールセットを提供しています。プロジェクトの要件に応じて適切なルールセットを選択します。
ルールセットの比較#
graph TB
subgraph "型情報なし"
A[recommended] --> B[strict]
A --> C[stylistic]
end
subgraph "型情報あり"
D[recommendedTypeChecked] --> E[strictTypeChecked]
D --> F[stylisticTypeChecked]
end
A -.->|型情報追加| D
B -.->|型情報追加| E
C -.->|型情報追加| F
| ルールセット |
説明 |
推奨対象 |
recommended |
基本的な推奨ルール |
すべてのプロジェクト |
strict |
より厳格なルール |
TypeScript経験者のチーム |
stylistic |
コードスタイルのルール |
スタイルの統一が必要な場合 |
recommendedTypeChecked |
型情報を使用した推奨ルール |
型安全性を重視するプロジェクト |
strictTypeChecked |
型情報を使用した厳格なルール |
高い品質基準が求められるプロジェクト |
stylisticTypeChecked |
型情報を使用したスタイルルール |
スタイルと型安全性の両方が必要な場合 |
recommendedルールセット#
最も基本的なルールセットで、明らかなバグやアンチパターンを検出します。
1
2
3
4
5
6
7
8
9
|
// eslint.config.mjs
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommended
);
|
主なルール例:
@typescript-eslint/no-unused-vars - 未使用変数の検出
@typescript-eslint/no-explicit-any - any型の使用を警告
@typescript-eslint/no-require-imports - CommonJSのrequireを禁止
strictルールセット#
recommendedに加えて、より厳格なルールを追加します。TypeScriptに精通したチームに推奨されます。
1
2
3
4
5
6
7
8
9
10
|
// eslint.config.mjs
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.strict,
tseslint.configs.stylistic
);
|
追加される主なルール例:
@typescript-eslint/no-non-null-assertion - 非nullアサーション(!)の使用を禁止
@typescript-eslint/prefer-nullish-coalescing - ||より??の使用を推奨
@typescript-eslint/no-unnecessary-condition - 不要な条件式を検出
strictルールセットの適用例#
以下のコードは、strictルールセットで検出される問題の例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// strictルールで検出される問題の例
// @typescript-eslint/no-non-null-assertion
const element = document.getElementById("app")!; // 非推奨
// 推奨される書き方
const element2 = document.getElementById("app");
if (element2) {
// element2を安全に使用
}
// @typescript-eslint/prefer-nullish-coalescing
const value = someValue || "default"; // 非推奨(0や""が無視される)
// 推奨される書き方
const value2 = someValue ?? "default"; // nullとundefinedのみ判定
|
型チェックを含むLinting(Typed Linting)#
typescript-eslintの真価は、TypeScriptの型情報を活用したLintingにあります。型情報を使用することで、より高度なバグ検出が可能になります。
Typed Lintingの設定#
型情報を使用するには、parserOptionsにprojectServiceを設定します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// eslint.config.mjs
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
},
},
}
);
|
strictTypeCheckedルールセット#
最も厳格なルールセットで、型情報を活用した高度なチェックを行います。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// eslint.config.mjs
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
},
},
}
);
|
Typed Lintingで検出できる問題#
型情報を使用することで、以下のような問題を検出できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// @typescript-eslint/no-floating-promises
// Promiseを適切に処理しないコードを検出
async function fetchData() {
return "data";
}
fetchData(); // エラー: Promiseが処理されていない
// 正しい書き方
await fetchData();
// または
fetchData().catch(console.error);
// または
void fetchData();
// @typescript-eslint/await-thenable
// awaitの不適切な使用を検出
const value = 42;
const result = await value; // エラー: awaitはPromiseに対して使用すべき
// @typescript-eslint/no-misused-promises
// Promiseの誤った使用を検出
const items = [1, 2, 3];
items.forEach(async (item) => {
await processItem(item); // エラー: forEachはasync関数を適切に処理しない
});
// 正しい書き方
for (const item of items) {
await processItem(item);
}
// または
await Promise.all(items.map((item) => processItem(item)));
|
パフォーマンスの考慮#
Typed Lintingは型情報の解析が必要なため、通常のLintingより時間がかかります。大規模プロジェクトでは以下の対策を検討してください。
- IDE統合: VS Codeなどのエディタでは、キャッシュにより高速に動作
- CI/CD: 重要なブランチ(main、developなど)へのプッシュ時のみ実行
- 段階的導入: まず
recommendedから始め、徐々にstrictTypeCheckedへ移行
Prettierの設定#
Prettierのインストール#
1
|
npm install --save-dev prettier
|
Prettier設定ファイルの作成#
プロジェクトルートに.prettierrcファイルを作成します。
1
2
3
4
5
6
7
8
9
|
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "always"
}
|
主な設定オプション:
| オプション |
説明 |
推奨値 |
semi |
セミコロンを付けるか |
true |
singleQuote |
シングルクォートを使用するか |
プロジェクトに応じて |
tabWidth |
インデント幅 |
2 |
trailingComma |
末尾カンマ |
"es5" |
printWidth |
1行の最大文字数 |
80〜100 |
.prettierignoreファイルの作成#
フォーマット対象外のファイルを指定します。
1
2
3
4
5
|
node_modules/
dist/
build/
coverage/
*.min.js
|
package.jsonにスクリプトを追加#
1
2
3
4
5
6
|
{
"scripts": {
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}
|
ESLintとPrettierの統合#
ESLintとPrettierは一部のルールが競合する可能性があります。eslint-config-prettierを使用して、競合するESLintルールを無効化します。
eslint-config-prettierのインストール#
1
|
npm install --save-dev eslint-config-prettier
|
ESLint設定の更新#
eslint-config-prettierを設定の最後に追加します。これにより、Prettierと競合するESLintルールが無効化されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// eslint.config.mjs
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier/flat";
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
},
},
},
eslintConfigPrettier // 必ず最後に配置
);
|
競合チェックツールの実行#
eslint-config-prettierには、競合するルールを検出するCLIツールが含まれています。
1
|
npx eslint-config-prettier src/index.ts
|
問題がなければ何も出力されません。競合するルールがある場合は警告が表示されます。
完全な設定例#
実際のTypeScriptプロジェクトで使用できる完全な設定例を示します。
ディレクトリ構造#
1
2
3
4
5
6
7
8
|
my-typescript-project/
├── eslint.config.mjs
├── .prettierrc
├── .prettierignore
├── tsconfig.json
├── package.json
└── src/
└── index.ts
|
eslint.config.mjs(完全版)#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
// eslint.config.mjs
// @ts-check
import eslint from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier/flat";
export default defineConfig(
// ESLintの推奨ルール
eslint.configs.recommended,
// typescript-eslintの厳格な型チェック付きルール
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
// TypeScriptパーサーの設定
{
languageOptions: {
parserOptions: {
projectService: true,
},
},
},
// カスタムルール
{
rules: {
// 未使用変数の設定(_で始まる変数は許可)
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
// 明示的な戻り値の型を推奨
"@typescript-eslint/explicit-function-return-type": [
"warn",
{
allowExpressions: true,
allowTypedFunctionExpressions: true,
},
],
// console.logの使用を警告
"no-console": ["warn", { allow: ["warn", "error"] }],
},
},
// テストファイルの設定
{
files: ["**/*.test.ts", "**/*.spec.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
},
},
// JavaScriptファイルでは型チェックを無効化
{
files: ["**/*.js", "**/*.mjs"],
extends: [tseslint.configs.disableTypeChecked],
},
// Prettierとの競合を解消(必ず最後)
eslintConfigPrettier
);
|
.prettierrc(完全版)#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf",
"useTabs": false,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"bracketSameLine": false
}
|
package.json(scripts部分)#
1
2
3
4
5
6
7
8
9
10
|
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"check": "npm run format:check && npm run lint",
"fix": "npm run format && npm run lint:fix"
}
}
|
VS Codeとの統合#
ESLintとPrettierをVS Codeと統合することで、ファイル保存時に自動的にフォーマットとLintの修正を行えます。
推奨拡張機能#
以下の拡張機能をインストールします。
- ESLint(
dbaeumer.vscode-eslint)
- Prettier - Code formatter(
esbenp.prettier-vscode)
.vscode/settings.json#
プロジェクトルートに.vscode/settings.jsonを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"eslint.useFlatConfig": true
}
|
.vscode/extensions.json#
チームメンバーに推奨拡張機能を提示します。
1
2
3
4
5
6
|
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
|
CI/CDでの活用#
GitHub Actionsを使用して、プルリクエスト時にLintとフォーマットチェックを自動実行する例を示します。
.github/workflows/lint.yml#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
name: Lint and Format Check
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Check formatting
run: npm run format:check
- name: Run ESLint
run: npm run lint
|
トラブルシューティング#
よくあるエラーと解決方法#
1. tsconfig.jsonが見つからないエラー
1
|
Error: Could not find tsconfig.json
|
解決方法: parserOptionsにtsconfigRootDirを追加します。
1
2
3
4
5
6
7
8
|
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
|
2. 特定のファイルがLintされないエラー
1
|
Parsing error: ESLint was configured to run on `<filename>` however, that TSConfig does not include this file
|
解決方法: tsconfig.jsonのincludeに該当ファイルを追加するか、eslint.config.mjsでdisableTypeCheckedを適用します。
3. Prettierとの競合エラー
ESLintがフォーマット関連のエラーを報告する場合、eslint-config-prettierが正しく設定されているか確認します。設定配列の最後に配置されている必要があります。
まとめ#
TypeScriptプロジェクトのコード品質管理において、ESLintとPrettierの適切な設定は非常に重要です。本記事で解説した内容を実践することで、以下のメリットが得られます。
- 型安全性の向上: typescript-eslintのstrictTypeCheckedルールにより、型に関するバグを早期に検出
- コードスタイルの統一: Prettierによる自動フォーマットで、チーム全体で一貫したコードスタイルを維持
- 開発効率の向上: VS Code統合により、コーディング中にリアルタイムでエラーを検出・修正
- 品質の担保: CI/CDでの自動チェックにより、品質基準を満たさないコードのマージを防止
プロジェクトの規模や要件に応じて、recommendedから始めて徐々にstrictTypeCheckedへ移行することで、段階的にコード品質を向上させることができます。
参考リンク#