はじめに

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
npx 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の設定

型情報を使用するには、parserOptionsprojectServiceを設定します。

 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行の最大文字数 80100

.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

解決方法: parserOptionstsconfigRootDirを追加します。

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.jsonincludeに該当ファイルを追加するか、eslint.config.mjsdisableTypeCheckedを適用します。

3. Prettierとの競合エラー

ESLintがフォーマット関連のエラーを報告する場合、eslint-config-prettierが正しく設定されているか確認します。設定配列の最後に配置されている必要があります。

まとめ

TypeScriptプロジェクトのコード品質管理において、ESLintとPrettierの適切な設定は非常に重要です。本記事で解説した内容を実践することで、以下のメリットが得られます。

  • 型安全性の向上: typescript-eslintのstrictTypeCheckedルールにより、型に関するバグを早期に検出
  • コードスタイルの統一: Prettierによる自動フォーマットで、チーム全体で一貫したコードスタイルを維持
  • 開発効率の向上: VS Code統合により、コーディング中にリアルタイムでエラーを検出・修正
  • 品質の担保: CI/CDでの自動チェックにより、品質基準を満たさないコードのマージを防止

プロジェクトの規模や要件に応じて、recommendedから始めて徐々にstrictTypeCheckedへ移行することで、段階的にコード品質を向上させることができます。

参考リンク