Claude Media
Claude CodeでTypeDoc警告を直しTSDocを整える手順

Claude CodeでTypeDoc警告を直しTSDocを整える手順

TypeDocの警告を失敗扱いにしてClaude Codeに直させる手順です。@linkの解決、exportされていない型、未文書化の3系統を分け、書き換えをsrcのコメントに限る権限設計まで示します。

TypeDocの警告をClaude Codeに直させるなら、typedoc --emit none --treatValidationWarningsAsErrors をStop hookに置くのが近道です。警告が1件でもあれば、Claudeは止まれずに出力を読んで直します。ただし警告の中身によって、直してよい場所が違います。

@link が解決できない警告はコメントを直せば消えます。「型がexportされていない」警告は、直し方の1つが export を足すことです。これはコメントではなく公開APIの変更になります。ここでは3系統の警告を分け、Claudeに触らせる範囲をsrcのコメントに絞る設計を示します。

TypeDocの警告は3系統に分かれる

TypeDocには validation というオプションがあり、生成前に文書を検査します。既定値は次のとおりです。

{
  "validation": {
    "notExported": true,
    "invalidLink": true,
    "invalidPath": true,
    "rewrittenLink": true,
    "notDocumented": false,
    "unusedMergeModuleWith": true
  }
}

notDocumented だけが既定でオフです。「未文書化の警告が出ない」のは、潰したからではなく見ていないからかもしれません。

Claudeに任せる観点では、次の3系統で考えると整理しやすくなります。

系統該当する検査直す場所Claudeに任せてよいか
リンク該当する検査invalidLink / rewrittenLink直す場所コメント内の {@link}Claudeに任せてよいか任せやすい
未文書化該当する検査notDocumented直す場所コメントを足すClaudeに任せてよいか任せられるが質に注意
export漏れ該当する検査notExported直す場所export の追加か設定Claudeに任せてよいか方針を人が決める

notExported は、ドキュメントが参照している型がexportされていないときに出ます。直し方が「コメントの修正」に収まらないのが、この系統の特徴です。

警告を失敗扱いにする

警告をエラーにするオプションは2つあります。treatWarningsAsErrors は報告されたすべての警告を致命的エラー扱いにします。treatValidationWarningsAsErrors は、検査(validation)で出た警告だけが対象です。

もう1つ押さえたいのが --emit none です。これはHTMLを書き出さず、変換と検査だけを走らせます。Claudeが編集のたびにdocsフォルダを書き換えずに済むので、完了条件の確認用に向きます。

npx typedoc --emit none --treatValidationWarningsAsErrors

notDocumented を有効にするなら、同じコマンドに --validation.notDocumented を足します。どの種類の宣言にコメントを要求するかは requiredToBeDocumented で決まります。既定では Enum / Function / Class / Interface / Property / Method / Accessor / TypeAlias などが対象で、Parameter や Constructor は含まれません。

Stop hookで「警告ゼロ」を完了条件にする

Stop hookは、終了コード2を返すとClaudeが止まるのを防ぎ、会話を続けさせます。stderrに書いた内容はClaudeへのフィードバックになります。この仕組みで、TypeDocの出力をそのまま読ませます。

.claude/hooks/typedoc-check.sh を作ります。

#!/bin/bash
cd "$CLAUDE_PROJECT_DIR" || exit 0
 
OUT=$(npx typedoc --emit none \
  --treatValidationWarningsAsErrors \
  --validation.notDocumented 2>&1) || {
  echo "$OUT" | tail -40 >&2
  exit 2
}
exit 0

.claude/settings.json には、Stopイベントとして登録します。

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/typedoc-check.sh"
          }
        ]
      }
    ]
  }
}

tail -40 で出力を切るのは、警告が数百件あるプロジェクトで会話が埋まるのを避けるためです。40件を直せば次の40件が見えるので、反復で減っていきます。

ここで1つ設計上の選択があります。Stop hookのドキュメントは、無限ループを避けるために入力の stop_hook_active を見て早期終了する例を示しています。上のスクリプトはこれを入れていません。入れると、Claudeが一度続行した後は警告が残っていても止まれるようになり、「警告ゼロ」が完了条件でなくなるためです。

代わりに安全弁は、Claude Code側の上限が担います。Stop hookが連続8回ブロックしても、間にClaudeのツール呼び出しがなければ、次のブロックは無視されてターンが終わります。ツールを呼ぶたびにこのカウントはリセットされます。警告が多く8回を超えて収束するプロジェクトでは、環境変数 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP で上限を上げられます。

リンク系の警告は、Claudeが一番直しやすい種類です。ただし「どう書けば解決されるか」を知らないまま直させると、解決しないリンクを書き続けます。CLAUDE.mdに書き方を渡しておくと、反復が減ります。

TypeDocは {@link} の参照先を、宣言参照(declaration reference)として解釈します。要点は次のとおりです。

  • 区切り文字は . / # / ~ の3種類
  • . は最も汎用的で、exportと静的メンバーを先に探し、見つからなければメンバーも探す
  • # はインスタンスのプロパティやインターフェースのメンバー、列挙メンバーを指す
  • ~ は名前空間やモジュールのexportだけを指す
  • module!Foo のように ! の前にモジュール名を置ける。{@link !Target} のように空にするとルートスコープから探す

TSDoc仕様の ~ は「ローカルをたどる」意味ですが、TypeDocでは「. より厳格な名前空間のexport指定」になります。VS Codeなどの解決と揃えたいなら、~ より . が無難です。

また useTsLinkResolution は既定でオンです。TypeScriptが解決できたリンクは、TypeDocの宣言参照ではなくTypeScript側の規則で解決されます。外部パッケージの型へのリンクは、externalSymbolLinkMappings でURLに対応づける形が用意されています。

CLAUDE.mdに書く内容は、たとえば次のようなものです。

## TSDocコメントの書き方
- 同じファイルや同じパッケージの宣言へは `{@link Name}` を使う
- クラスのインスタンスメンバーは `{@link Class#member}`、静的メンバーは `{@link Class.member}`
- オーバーロードは `{@link foo:1}` のように番号で指す
- 外部パッケージの型は `{@link pkg!Name}`。解決できないときは `{@link}` を外してコードスパンにする
- `@param` は `@param name - 説明` の形で、名前の後にハイフンを置く

最後の @param の書式は、TSDocの仕様に沿ったものです。名前、ハイフン、説明の順で書きます。

「型がexportされていない」警告は人が決める

notExported は、公開APIが参照する型がエントリポイントからexportされていないときに出ます。直し方は2通りあります。

  • 型を公開に加える。エントリポイントに export を足す
  • 意図的に公開しないと決める。intentionallyNotExported にシンボル名を列挙する

どちらも、コメントの修正ではありません。1つ目はパッケージの公開APIを広げます。2つ目はdocsの警告を恒久的に黙らせます。Claudeが「警告を消す最短手」として前者を選ぶと、内部型がそのまま公開に漏れます。

運用としては、CLAUDE.mdに次のように書いておきます。

## TypeDocの警告の扱い
- invalidLink / notDocumented: srcのコメントだけを直す
- notExported: 直さない。警告の出た型名と参照元を一覧にして報告する
- typedoc.json と tsconfig.json は編集しない

書き換えをsrcのコメントに限る

CLAUDE.mdの指示は、守られない場合があります。権限と検査で補強します。

まず権限です。ReadとEditの規則はgitignore形式のパターンを使います。Edit(src/**) は作業ディレクトリ直下のsrc配下に限って編集を許可します。許可リストに入れるのはこれだけにし、TypeDocの設定は拒否に回します。

{
  "permissions": {
    "allow": [
      "Edit(src/**)",
      "Bash(npx typedoc *)"
    ],
    "deny": [
      "Edit(typedoc.json)",
      "Edit(tsconfig*.json)",
      "Edit(package.json)"
    ]
  }
}

ファイルへの規則は Edit に書きます。Write(path) のようなパス付き規則は書いても一致しないので、Writeを止めたいときもEditで書きます。denyが設定の保護、allowがsrcの許可という分担です。拒否規則が何にも一致しない場合の警告はdenyルールの「matches no tool」警告で扱っています。

ただし Edit(src/**) は、srcの中のコードも書き換えられます。コメント以外の変更を止めるには、もう一段が要ります。Stop hookで差分を見ます。

#!/bin/bash
cd "$CLAUDE_PROJECT_DIR" || exit 0
 
CODE_CHANGES=$(git diff -U0 -- src \
  | grep -E '^[+-]' \
  | grep -vE '^(\+\+\+|---)' \
  | grep -vE '^[+-][[:space:]]*(/\*\*|\*|//)')
 
if [ -n "$CODE_CHANGES" ]; then
  echo "src にコメント以外の変更があります。TypeDocの警告対応はコメントだけにしてください:" >&2
  echo "$CODE_CHANGES" | head -20 >&2
  exit 2
fi
exit 0

これはコメント行の見分けを行頭の記号で近似した簡易版です。行頭が * で始まる複数行の式のようなコードは、誤ってコメント扱いされます。厳密に守りたい場合は、TypeScript ASTでコメント以外のトークン列が変わっていないことを比較するスクリプトに置き換えます。

2つのhookは、Stop の hooks 配列に並べて登録します。1つ目で警告ゼロを、2つ目でコメントだけの変更を確かめます。複数のhookの結果は合成して扱われます。

3系統の警告を潰す実際の流れ

作業の流れは次の順番になります。

手順

警告ゼロまでの反復

  1. 1

    現状の警告を一覧にする

    npx typedoc --emit none --validation.notDocumented を一度手で実行し、系統別の件数を見ます。

  2. 2

    リンク系から直させる

    invalidLink と rewrittenLink はコメントだけで直ります。CLAUDE.mdの宣言参照のルールを渡して依頼します。

  3. 3

    未文書化はまとまった単位で

    ファイルやモジュール単位で依頼し、@param name - 説明 と @returns を含めた形で書かせます。

  4. 4

    export漏れは一覧で受け取る

    Claudeに直させず、型名と参照元の一覧を出させます。人が公開するか intentionallyNotExported に回すかを決めます。

未文書化の警告は、コメントを足せば消えます。その分、型名を言い換えただけの形式的なコメントでも消えてしまう点に注意が要ります。「UserId はユーザーIDです」のようなコメントは、警告を消しても情報を増やしません。依頼のときは、戻り値の意味、例外条件、単位のように型から読み取れない情報を書かせると、警告の解消がドキュメントの改善につながります。

警告を減らす近道としての除外設定

警告が多すぎて収束しないとき、設定で見る範囲を絞る手があります。

  • excludeInternal: @internal タグの付いた宣言を出力から外す
  • excludePrivate: private メンバーを外す(既定でオン)
  • excludeNotDocumented: コメントのない宣言をドキュメントから外す。対象の種類は excludeNotDocumentedKinds で絞れる
  • intentionallyNotDocumented: 未文書化を意図的に許す名前を列挙する

excludeNotDocumented は「警告を出す」のでなく「宣言ごと出力から消す」ので、notDocumented の検査とは別物です。警告を消すためにこれを使うと、未文書化のAPIがdocsから消えるだけで、品質は上がりません。これらの設定はClaudeに触らせず、人がレビューして決めるものです。

SphinxやMkDocsでも、警告を失敗扱いにする考え方は同じです。Sphinxの警告を直させる手順やMkDocsのstrictビルドと比べると、TypeDocに固有なのは宣言参照の書き方と、export漏れが公開APIの判断に直結する点です。Hooksの仕組み全体はClaude Code Hooks完全ガイドにまとめています。

まとめ

TypeDocの警告は、見た目は1種類でも、直す先がコメントと公開APIに分かれます。完了条件は --treatValidationWarningsAsErrors のStop hookに置き、書き換えは Edit(src/**) とコメント限定の差分検査で縛ります。notExported だけは、直させず一覧で受け取って人が決める。この線引きを最初に置くと、警告ゼロの達成が公開APIの意図せぬ拡大と引き換えになる事態を避けられます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. typedoc.org/documents/Options.Validation.html
  2. typedoc.org/documents/Declaration_References.html
  3. typedoc.org/documents/Options.Comments.html
  4. typedoc.org/documents/Options.Input.html
  5. tsdoc.org/pages/tags/param
  6. code.claude.com/docs/en/hooks-guide
  7. code.claude.com/docs/en/hooks
  8. code.claude.com/docs/en/permissions
この記事を共有:XはてブLinkedIn