AIと共に育てるコードベース:散らばった型定義をリファクタリングした実践記録
📝 概要
AIエージェントにコーディングを任せ、高速で開発を進めていました。しかし、ある問題が発覚します。それは、型定義に関する設計指示を怠ったために、interfaceやtypeが無秩序に各ファイルへ散らばってしまったことです。
これは、AIコーディングを実践する多くの開発者が陥りがちな「見過ごされた技術的負債」ではないでしょうか。AIは指示通りにコードを生成しますが、プロジェクト全体の整合性や将来のメンテナンス性までを考慮した「設計」は、人間が主導権を握る必要があります。
この記事では、この「AI開発によって生じた型定義のカオス」という問題を、AIコーディングアシスタント(Gemini Code Assist)と協力して解決していくリファクタリングの全プロセスを記録します。
目指すのは、単なるコード整理ではありません。AIを「全自動の魔法の杖」ではなく「極めて優秀な専門家アシスタント」として扱い、人間が設計の主導権を握りながら協調作業を進めるという、次世代の開発スタイルを実践することです。
⚠️ 問題の発見と症状
開発を進める中で、以下のような症状が顕在化してきました。
- 重複した型定義:
TagGroupという全く同じインターフェースが、3つの異なるコンポーネントファイルに存在していた。 - 関心の散在: ブログ記事に関連する型 (
Post,PostSummary,BlogPost) が、データアクセス層や自動生成ファイルなど、複数の場所に点在していた。 - 見通しの悪さ: 新しい機能を追加する際、どの型を使えば良いのか、あるいは新しい型をどこに定義すべきか判断するのに時間がかかる。
これは、コードベースの健全性を損ない、将来の開発速度を低下させる明確なサインです。
🔍 調査と方針決定:AIとの対話
この問題を解決するため、AIアシスタントに相談を持ちかけました。
🧑💻: 「散らばったTypeScriptの型定義を一つのファイルにまとめたい。関連ファイルを全部開けば良い?」
🤖: 「はい、関連ファイルをすべて開くのは非常に効果的です。開かれているファイル全体をコンテキストとして読み込み、横断的に型定義とその利用箇所を把握できます。」
単純に「全部まとめて」と指示することもできましたが、それでは保守性の低い巨大な「神ファイル」が生まれるリスクがあります。そこで、さらに議論を深めました。
🧑💻: 「一つのファイルに集約して循環参照などで壊れる懸念はある?」
🤖: 「良い視点です。最も注意すべきは循環参照です。対策として import type を徹底することが重要です。また、すべてを一つにまとめるのではなく、ドメインごと(User関連、Product関連など)にファイルを分割するのがおすすめです。」
この対話を通じて、私たちは闇雲にリファクタリングするのではなく、明確な戦略を持って進めることにしました。
決定したワークフロー
AIとの議論の末、以下の**「分析 → 設計(人間) → 実行」**という、人間が主導権を握るワークフローを採用しました。
- **分析 **: AIに重複・関連する型をリストアップさせ、現状を客観的に把握する。
- **設計 **: AIの分析結果を元に、どの型をどこに集約するか、あるいは集約しないかを人間が判断・設計する。
- **実行 **: 人間が決定した設計に基づき、具体的なコードの書き換え作業をAIに指示する。
🔧 実装フェーズ:最初のステップ
ワークフローに従い、まずは最も分かりやすい問題から着手します。
ステップ1: 関連ファイルの特定と一括オープン
まず、AIにプロジェクト内の型定義をリストアップさせ、そのファイルパス一覧を作成しました。
次に、ターミナルからVS Codeのコマンドを使い、リストアップされた数十のファイルを手作業ではなく一括で開きます。
# bash用のコマンド(PowerShellとは構文が違う点に注意)
# -r オプションで「既存のウィンドウで開く」のがポイント
code -r $(cat 'path/to/型リスト.txt' | grep '^app\\.*:' | cut -d':' -f1 | sort -u)この時点で、シェルの違い(bash vs PowerShell)や、コマンドのオプション(-r)といった細かい部分で躓きましたが、これもAIと対話しながら解決しました。
ステップ2: AIによる分析
関連ファイルをすべて開いた状態で、AIに分析を依頼しました。
🧑💻: 「開いているファイルを確認して」
🤖: 「承知いたしました。分析の結果、TagGroup というインターフェースが3つのファイルで完全に重複しています。これは集約の最有力候補です。」
ステップ3: 人間による設計とAIへの実行指示
AIの分析は妥当でした。まずはこの TagGroup の集約から始めることにします。集約先として、ブログ関連の仕様をまとめる app/specs/blog/types.ts を指定しました。
🧑💻: 「TagGroup を app/specs/blog/types.ts に集約して」
🤖: 「承知いたしました。」
この指示に基づき、AIは以下の3つの変更を提案・実行しました。
- 集約:
app/specs/blog/types.tsにTagGroupを定義し、exportする。 - 削除: 元の3つのファイルから
TagGroupの定義を削除する。 - 更新:
import type { TagGroup } from '~/specs/blog/types';のように、import文を更新する。
結果、重複が解消され、TagGroup の定義は一箇所に集約されました。これで、将来の仕様変更にも強く、見通しの良いコードベースへの第一歩を踏み出すことができました。
このシリーズの記事
- Part 1: 単純な重複の排除
- Part 2: 『唯一の真実の源』の確立
- Part 3: 『関心の分離』の実践
- Part 4: ドメイン知識の集約
- Part 5: 『生きた仕様書の完成』