TL;DR

  • コーディング規約はドキュメントに書くだけでなく、TypeScript のコンパイラオプションやリンタのルールで強制する。
  • 既存のルールで表せない規約は、ESLint の no-restricted-syntax で特定の構文を禁止できる。
  • この項目は日本語版の訳者によるオリジナルで、本書の各項目に対応する設定を紹介している。

内容

規約を設定で強制する

コーディング規約はドキュメントに書くだけで終わらせず、コンパイラオプションやリンタの設定に反映したほうがよい。一般に問題とされる書き方(型アサーションなど)に例外的な使い道がある場合でも、頻度が高くなければ設定で禁止することを検討する。TypeScript やリンタのエラーは @ts-ignore や @ts-expect-error のコメントで無効にできるので、禁止された書き方をするにはコメントを書かざるを得なくなる(項目43)。これにより、問題のあるコードがうっかり書かれることがなくなり、コードレビューでの見落としも防げる。ただし、やりすぎると @ts-expect-error のコメントだらけになって読みにくくなる。

どこまでエラーにするか迷ったときは、新規プロジェクトなら後から緩めるのは簡単なので、厳しめに設定する。既存のプロジェクトなら、その設定を入れる理由を説明できるかをまず考える。

no-restricted-syntax で独自の規約を書く

規約に合うルールが見つからない場合は、ESLint の no-restricted-syntax を使う。CSS セレクタに似た書き方で構文を指定し、その構文の利用を禁止できる。次の例は、null や undefined を含むユニオン型の型エイリアスを禁止する。

// eslint.config.mjs
export default tseslint.config(
  // ...
  {
    // ...
    rules: {
      "no-restricted-syntax": [
        "error",
        {
          selector:
            "TSTypeAliasDeclaration > " +
            ".typeAnnotation[type=TSUnionType] > " +
            ":matches(TSNullKeyword, TSUndefinedKeyword)",
          message: "null や undefined を含むユニオン型の型エイリアスを使ってはいけません",
        },
      ],
    },
  },
)

ルールを書くときは typescript-eslint の Playground が便利である。AST も表示できるので、禁止したいコードの AST ノードを確かめながら selector を書き、ルールが期待どおりに動くところまで確認できる。

本書の項目に対応する設定

ルール名は、特に断りがなければ typescript-eslint のものである。

訳者による解説

本書の内容は主張が強い(opinionated)ので、"strict": true や typescript-eslint の recommended のような一般的な設定だけではカバーできない。また、ソフトウェア開発はチームで行うので、1 人が本書を読んで意識を高めても意味がない。そこで、本書の推奨をコンパイラオプションやリンタで強制する。見逃しがなくなり、後から加わるメンバーにも優しい。ただし、ルールが複雑になるとメンテナンスのコストも高くなる。

キーワード

自分の理解

Effective Rust にも似た項目があった(項目29 Clippyに耳を傾けよう)。