TypeScript 上級は『コードを書く時間を減らす型』
基礎を超えた TypeScript の型は、ライブラリ設計やAPI境界の設計で力を発揮します。本記事では編集部の視点で、実務で効く上級パターンを公開情報をもとに整理します。型理解度を一段引き上げる5パターンを順に紹介。TypeScript ロードマップ も合わせてどうぞ。
1. Conditional Types で型を分岐
(1) T extends U ? X : Y の基本形。(2) distributive な挙動:Union に対して分配される。(3) infer:型の中の型を取り出す。(4) ユースケース:戻り値型の抽出、引数型の操作。(5) Utility Types の中身:ReturnType / Parameters はこれで定義されている。
2. Branded Types で『同じ string』を区別
(1) type UserId = string & { __brand: "UserId" }。(2) UserId と PostId を取り違えない:コンパイル時に検出。(3) 金額・通貨・IDの区別に有効。(4) generation 関数を1つだけ用意。(5) nominal typing の代替として広く使われる。
3. Template Literal Types で文字列を型化
(1) `/users/${string}` でURLパスを型化。(2) イベント名の制約:onUserCreated 等の命名規約を型で強制。(3) SQL や URL の補完に応用。(4) 注意:複雑になりすぎるとIDEが重くなる。(5) OAS から型生成と組み合わせるとAPI境界の安全性が一段上がる。
4. Discriminated Union で網羅性チェック
(1) type Action = { type: "A"; ... } | { type: "B"; ... }。(2) switch で type を分岐すると各ブランチで型が絞れる。(3) never で網羅性チェック:未処理ケースをコンパイルエラー化。(4) 状態遷移の表現に最適。(5) Result<T,E> のような関数型パターンとも相性が良い。
5. 型安全DSLとビルダー
(1) method chain で状態を型に反映:ビルダーパターン。(2) Zod / Valibot / Effect Schema:ランタイム検証と型推論を両立。(3) tRPC:型安全RPCの代表格。(4) OAS → 型 → クライアントのパイプライン。(5) 過剰な型は禁物:チームで読める範囲を超えるとメンテ性が下がる。REST API設計 もご参考に。
失敗しがちなパターン
(1) any で逃げる癖:型の恩恵を失う。(2) 過度な型パズル:可読性が極端に低下。(3) strict 設定を緩める:noImplicitAny/strictNullChecks は維持。(4) 型と実行の二重メンテ:Zod等で1つの真実源にまとめる。(5) tsc が遅くなる:複雑な Conditional Types は型推論コストが高い。対策は、(1)unknown 経由のnarrowing、(2)型の複雑度をレビュー対象、(3)strict維持、(4)スキーマ駆動、(5)型のコンパイルタイム計測、です。