Dev Study
← 解説「ESLintとangular-eslint — 書き方の問題を機械に見つけさせる」に戻る

サンプルコードで身につける: ESLintとangular-eslint — 書き方の問題を機械に見つけさせる

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1ng addでangular-eslintを導入する

導入はng addの一発で完了します。パッケージの追加だけでなく、設定ファイルの生成とangular.jsonへのlintターゲット登録まで自動で行われます。導入直後からng lintが使えます。

# angular-eslint を導入する(v17 以降はこれが正式な手順)
ng add angular-eslint

# 自動で行われること:
#   ・ESLint 本体と angular-eslint 一式のインストール
#   ・eslint.config.js(設定ファイル)の生成
#   ・angular.json に lint ターゲットを登録

# 導入できたか確認
ng lint

2ng lintの出力を読む

ng lintの出力には、ファイル名・行番号・重大度・メッセージ・ルール名が並びます。最後のルール名が調べるときの手がかりです。ルール名で検索すると、なぜ悪いのか・どう直すのかの解説が見つかります。

ng lint

# 出力例:
# /src/app/user-list/user-list.ts
#   3:10  error  'Router' is defined but never used
#                @typescript-eslint/no-unused-vars
#   12:22  error  Unexpected any. Specify a different type
#                @typescript-eslint/no-explicit-any
#
# ✖ 2 problems (2 errors, 0 warnings)

# 読み方: 行:列 / 重大度 / メッセージ / ルール名
# ルール名(@typescript-eslint/...)で検索すると公式の解説が見つかる

3未使用importとanyを直す

最も頻繁に出る2つの指摘の直し方です。未使用importは消すだけ、anyは実際のデータの形を型として書きます。anyを避けるだけで、その後の補完と型チェックが効くようになります。

// ── Before: 2つのルールに怒られるコード ──
// import { Router } from '@angular/router';  // no-unused-vars: 使っていない
//
// function greet(user: any) {                // no-explicit-any: any は禁止
//   return 'こんにちは、' + user.name + 'さん';
// }

// ── After: 未使用 import は消し、any は具体的な型にする ──
type User = { name: string };

function greet(user: User): string {
  return 'こんにちは、' + user.name + 'さん';
}

4--fixで自動修正できるものを片付ける

ルールには自動修正に対応しているものがあり、--fixを付けると機械的に直せる指摘が一括で修正されます。導入直後の大量のエラーも、まず--fixを実行してから残りを手で直すと効率的です。

# 自動修正に対応した指摘を一括で直す
ng lint --fix

# 例: 自動修正できるもの
#   ・未使用の import の削除
#   ・const にできる let の置き換え(prefer-const)

# 例: 自動修正できないもの(手で直す)
#   ・any をどの型にするか(人間にしか分からない)
#   ・複雑すぎる関数の分割

# --fix 後にもう一度実行して、残りを確認する
ng lint

5Angular固有ルール — セレクタの接頭辞

angular-eslintのcomponent-selectorルールは、セレクタの接頭辞・記法・種別を強制します。全コンポーネントがapp-で始まっていれば、テンプレート内で自作の部品と外部の部品を一目で区別できます。

// eslint.config.js(抜粋)— ng add が生成する Angular 固有ルールの例
// rules: {
//   '@angular-eslint/component-selector': [
//     'error',
//     { type: 'element', prefix: 'app', style: 'kebab-case' },
//   ],
// },

// ── このルールに違反する例 ──
// @Component({ selector: 'userCard', ... })   // 接頭辞なし + キャメルケース

// ── ルールに従った例 ──
// @Component({ selector: 'app-user-card', ... })  // app- + ケバブケース