TypeScriptのUtility Typesは、既存の型を変換・加工するための組み込みジェネリクスです。これらを活用することで、同じような型定義を繰り返し書く必要がなくなり、型の変更が一箇所に集約されます。「TypeScriptを書いているが型を手書きで全部定義している」という場合、Utility Typesの導入でコードが大幅にシンプルになる可能性があります。この記事では実務でよく使う7種類を、具体的なユースケースとともに解説します。
Partial<T> と Required<T> — すべてのプロパティを任意・必須に
`Partial<T>` は型 `T` のすべてのプロパティを省略可能(`?`)にします。フォームの「更新」処理でよく使われます。たとえば `User` 型の一部フィールドだけを更新したい場合、更新用の引数型を `Partial<User>` にすることで「存在するフィールドだけを渡す」というパターンを型安全に表現できます。`Required<T>` はその逆で、すべてのオプショナルプロパティを必須にします。設定オブジェクトにデフォルト値を適用した後、最終的に全フィールドが埋まっていることを保証する場合などに有効です。両者を組み合わせると `Required<Partial<T>>` は元の型と等価ですが、途中のパイプラインで型を柔軟に扱う際に応用できます。
Pick<T, K> と Omit<T, K> — 必要なフィールドだけ抜き出す・除外する
`Pick<T, K>` は型 `T` から特定のプロパティ `K` だけを持つ新しい型を作ります。`Pick<User, "id" | "name">` とすれば、`id` と `name` だけを持つ型になります。APIレスポンスからUI表示に必要なフィールドだけを抽出したコンポーネント用の型を作る場合や、機密フィールド(パスワードハッシュなど)を除いたパブリックな型を定義するのに便利です。`Omit<T, K>` はその逆で、特定のプロパティを除外した型を作ります。`Omit<User, "password" | "salt">` でパスワード関連フィールドを取り除いた安全なユーザー型を定義できます。フォームの `id` や `createdAt` など、作成時には存在しないフィールドを除く `Omit<Article, "id" | "createdAt">` という使い方もよく見られます。
Record<K, V> — キーと値の型を指定したオブジェクト型
`Record<K, V>` はキーの型 `K` と値の型 `V` を指定したオブジェクト型を作ります。`Record<string, number>` は「文字列キーで数値を持つオブジェクト」を表し、辞書・マップ型として使われます。より具体的には `Record<"success" | "error" | "loading", string>` のようにキーをユニオン型にすることで、特定のキーしか持てないオブジェクトを型安全に表現できます。ステータスコードと表示メッセージのマッピング、言語コードと翻訳文字列の対応表など、「固定されたキーセットに値を対応させる」パターンで頻繁に使われます。インデックスシグネチャ `{ [key: string]: V }` との違いは、Recordはキーを列挙型に絞れる点です。
ReturnType<T> と Parameters<T> — 関数の型から型を抽出する
`ReturnType<typeof fn>` は関数 `fn` の戻り値の型を取得します。外部ライブラリの関数が返す型を手書きで定義し直さず、`ReturnType<typeof libraryFn>` で自動的に取得できるため、ライブラリのアップデートに追従しやすくなります。`Parameters<typeof fn>` は関数の引数の型をタプルとして取得します。`Parameters<typeof createUser>[0]` で第一引数の型だけを取り出すことができます。これらを組み合わせると、「ある関数をラップした別の関数を型安全に書く」場面で役立ちます。たとえばAPIコールをラップするキャッシュ関数を作る場合、元の関数の引数と戻り値の型を `Parameters` と `ReturnType` で取得して使えます。
Readonly<T> と型の不変性
`Readonly<T>` はすべてのプロパティを読み取り専用にし、変更を試みるとコンパイルエラーになります。設定オブジェクト・定数・Reduxのstateなど「変更されてはいけないデータ」を型レベルで保護できます。`Object.freeze()` はランタイムで変更を防ぎますが型推論が弱く、`Readonly<T>` はコンパイル時のチェックに特化しています。配列の場合は `ReadonlyArray<T>`(または `readonly T[]`)を使います。ネストされたオブジェクトのプロパティはシャローなReadonlyのため、深い部分まで保護したい場合は `DeepReadonly` を自前で定義するか、utility-typesライブラリを使います。型定義ファイルやAPIのレスポンス型など、外部から渡されて変更すべきでないデータに積極的に適用すると、意図しないミューテーションによるバグを事前に防げます。
まとめ
Utility Typesは「型の変換・加工」のための強力な道具です。Partial・Required・Pick・Omitは型の絞り込みに、RecordはマップオブジェクトのKV型定義に、ReturnType・Parametersは関数型の抽出に、Readonlyは不変性の保証に使います。これらを組み合わせると「新しい型を一から書く」必要が大幅に減り、型の変更が一箇所に集約されます。JSON to TypeScriptツールで既存のJSONデータから型定義の土台を生成した後、Utility Typesで加工するという組み合わせも効率的です。