TypeScriptで開発していると、既存の型を再利用して少し加工したい場面が頻繁に出てきます。たとえば一部のプロパティをオプショナルにしたい、特定のキーだけ抜き出したい、関数の戻り値だけを型にしたいといった操作です。これらを毎回手書きで実装するのは大変ですが、TypeScriptにはこうした操作を助けるユーティリティ型が多数用意されています。本記事では「TypeScript utility types 一覧」の検索意図を踏まえ、主要なユーティリティ型を網羅的に解説し、用途別の使いどころも具体的に紹介します。読み終えれば、日々の型設計がより安全で効率的になります。
目次
TypeScript utility types 一覧:基本から応用まで網羅する型操作
この見出しでは、TypeScriptのutilityとtypesの一覧を基本操作から高度な応用まで幅広く網羅します。TypeScriptに組み込まれているユーティリティ型は多数存在し、対象をオブジェクト操作、ユニオン操作、関数/コンストラクタ操作、文字列操作などカテゴリーに分けて理解すると把握しやすくなります。ここではまず代表的なものを全体像として整理します。
オブジェクト操作系ユーティリティ型
オブジェクト型(プロパティを持つ型)に対して、指定プロパティをオプショナル/必須にしたり、プロパティの追加・削除・読み取り専用化などを行う型操作群です。コード設計で頻繁に登場します。
ユニオン・条件型操作系ユーティリティ型
ユニオン型(複数の候補を持つ型)を絞り込んだり除外したりする型操作です。条件型(T extends U ? …)やユニオン分配なども含み、型安全なフィルタリングや抽出に役立ちます。
関数/コンストラクタ型操作系ユーティリティ型
関数の引数や戻り値、コンストラクタのパラメータやインスタンス型を取り扱う型操作群です。外部ライブラリや既存APIの型をラップしたり、型を流用したりする際に非常に役立ちます。
文字列操作系ユーティリティ型
文字列型に対する大文字/小文字変換、頭文字のキャピタライズなどの操作を型レベルで行うための型です。テンプレート文字列型とも連携して、型名やキー名を制約するような高度な用途でも使用できます。
その他の特殊または制御系ユーティリティ型
型推論の制御やthisパラメータの抽出、非null非undefinedの絞込みなど、使う機会が少ないが知っておくと型設計がより厳密になる型操作群です。
各ユーティリティ型の具体的な一覧と使い所
ここからは、先ほどのカテゴリに分けて具体的なユーティリティ型を名前と構文、用途例を交えて説明します。読者が「どの型を使えばいいか」を直感的に判断できるようになります。
オブジェクト操作系ユーティリティ型
代表的な型には以下があります:
Partial<T>:型Tの全プロパティをオプショナルにする。部分だけ更新するPATCH系操作に最適です。既定の型を値として使う際、記述量を減らせます。Required<T>:オプショナルなプロパティをすべて必須にする。設定オブジェクトのマージ後など、完全なデータが確実な場面に。Readonly<T>:プロパティを読み取り専用にする。ミュータブルな操作を禁止したい状態に。Pick<T, K>:型Tから指定キーKのみを抽出する。公開APIのレスポンスや公開インターフェース削減に。Omit<T, K>:型Tから指定キーKを除去する。セキュリティ目的や不要フィールドを排除する用途に。Record<K, V>:キーの集合Kと値の型Vからオブジェクト型を作成。辞書型やマップ表現に使われます。
ユニオン・条件型操作系ユーティリティ型
こちらはユニオン型や条件型を操作する型です:
Exclude<T, U>:TからUに割り当て可能なユニオンメンバーを除外する。不要なケースを排除したいとき。Extract<T, U>:TからUに割り当て可能なメンバーのみを残す。許可されたケースの抽出に。NonNullable<T>:ユニオン型からnullとundefinedを除外する。値の存在を保証したいときに。Awaited<T>:Promise型を再帰的にアンラップする。非同期処理でPromise<Promise>のようなネストされた型を扱う際に。
関数/コンストラクタ型操作系ユーティリティ型
関数やクラスの型を扱う次のユーティリティがあります:
Parameters<T>:関数型Tが取る引数の型をタプルで取得。引数を再利用したりラップしたりするとき。ConstructorParameters<T>:コンストラクタ関数の引数型を取得。クラスのnew操作を抽象化するときに。ReturnType<T>:関数型Tの戻り値の型を取得。既存関数をラップする際に型の一貫性を保つ。InstanceType<T>:コンストラクタ型Tから生成されるインスタンスの型を取得。動的にインスタンスを扱う場合など。ThisParameterType<T>:関数型Tのthisパラメータの型を抽出。thisを明示的に型設計する場面で。OmitThisParameter<T>:thisパラメータを持つ関数型からthisを取り除いた型を取得。関数型をthisなしで扱いたいときに。
文字列操作系ユーティリティ型
テンプレート文字列型などと組み合わせて使われる文字列操作型の例は以下の通りです。型名やキー名に制約を設ける用途で重宝します。
Uppercase<S>:文字列Sをすべて大文字に変換した文字列型を返します。Lowercase<S>:文字列Sをすべて小文字に変換した文字列型を返します。Capitalize<S>:文字列Sの先頭字を大文字に変換します。Uncapitalize<S>:文字列Sの先頭字を小文字に変換します。
その他の特殊または制御系ユーティリティ型
これらはややマニアックですが、型安全性を高めたり型推論をコントロールする用途で非常に強力です。
ThisType<T>:オブジェクトリテラル内でのthisの型を指定するための型。ミックスインパターンなどで使用。NoInfer<T>:型推論の方向性を制限して予期しない型推論を防ぐ。ジェネリクスが複雑なコードで活躍。
利用シーン別:どのユーティリティ型を使うべきか
ユーティリティ型はいくつかのパターンに分けて使われることが多いです。場面に応じて適切な型を選ぶことが、型の堅牢性と可読性を高める鍵となります。以下は典型的利用シーンとおすすめ型の組み合わせです。
API設計とレスポンス整形
バックエンドとやりとりするAPIでは、データベースの型とは異なるレスポンス型を返すことがあります。たとえばパスワードなどセンシティブ情報を除く場合、元の型から不要なプロパティを除去する必要があります。そういったときには Omit< が活躍します。
また、部分的な更新(PATCH 等)を受ける API では、クライアント側が送るデータが部分的であってよいケースが多いため、 Partial< を使います。必須フィールドを確実に持たせたい場面では Required< を組み合わせたりします。
フォームの状態管理やコンポーネントのプロパティ型
React や Vue 等のフロントエンドでは、フォームの入力状態を追うために「まだ入力されていない値がある」状態を扱うことがあります。こうした状態では不完全なオブジェクトを扱うことになるので Partial< が役立ちます。
一方で、コンポーネント外に公開する型は不変性が重要です。オブジェクトの内容を変更できないようにしたり、コピー操作を強制するような設計を目指すなら Readonly< を使ってミュータブルな操作を防ぎます。
型安全なユニオン操作と条件分岐
ユニオン型から特定のケースだけを許可したい、あるいは null や undefined を除きたい場面では Extract< や Exclude<、 NonNullable< が中心になります。外部から受け取るデータの型が不確定なとき、型安全に条件分岐できるようにこれらを活用します。
関数やクラスの型再利用とラッパー関数設計
他の関数を受け取って内部で使うラッパー関数や、高階関数を設計する場面では、引数の型を再利用したり戻り値の型を抽出したりすることがあります。そういうときには Parameters< や ReturnType< が非常に便利です。それによって対外的な型を一致させて保守性を向上できます。
比較表:主要ユーティリティ型の特徴を一目で確認
以下の表は代表ユーティリティ型の機能比較です。使い分けを判断する際の参考になります。
| 型名 | 目的 | オプショナル/必須 | 読み取り専用 | ユニオン操作あり |
|---|---|---|---|---|
| Partial<T> | すべてのプロパティをオプショナルに | 可 | 否 | 否 |
| Required<T> | すべて必須に | 要 | 否 | 否 |
| Readonly<T> | 再割当て禁止に | 否 | 可 | 否 |
| Pick<T,K> | 特定キーのみ抽出 | 元の状態保持 | 否 | 否 |
| Omit<T,K> | 特定キーを除外 | 元の状態保持 | 否 | 否 |
| Exclude<T,U> | ユニオンから除外 | – | – | 可 |
| ReturnType<T> | 関数の戻り値型取得 | – | – | – |
最新に追加されたユーティリティ型と注意事項
TypeScriptはバージョンアップに伴って新しいユーティリティ型が追加されています。また用法には注意すべき点がいくつかあります。以下では比較的新しく追加された型と、使う際の誤解しやすいポイントを整理します。
最近追加/拡張された型
従来からある Partial、Required、Readonly、Pick、Omit、Record などに加えて、非同期処理や推論制御に関する型の役割が強化されています。たとえば Awaited という Promise を再帰的にアンラップする型や、NoInfer という型推論をブロックする仕組みが標準で取り入れられています。これらは最新の仕様で使用できます。
浅い操作と深い操作の違い
多くのユーティリティ型は「浅い(shallow)」操作です。つまりオブジェクトのプロパティがさらにオブジェクトを含んでいた場合、内部のネストされたプロパティまで型操作(Optional化/Readonly化など)が及ぶわけではありません。深いネストがある場合は自作の DeepPartial や DeepReadonly のような補助型を書く必要があります。
型推論とジェネリクスの制御時の落とし穴
NoInfer や ThisParameterType、OmitThisParameter のような型は型推論に影響するため、コードの可読性や予期しない型推論の結果の原因となることがあります。型が複雑になると型エラーが出にくくなる反面、何が正確な型か追いにくいこともあるため、こうした型は用途に限定して使うのが望ましいです。
まとめ
ここまで TypeScript の utility types 一覧を基本から応用、最新拡張、注意事項まで幅広く解説しました。どれかを知っている、または使ったことがあるというものも多いと思いますが、
重要なのは単に型を知っていることではなく、どの場面でどの型を選ぶかを判断できることです。オブジェクトの部分更新では Partial、公開データ整形では Pick/Omit、戻り値や引数の抽出では ReturnType や Parameters、ユニオンの絞込みには Exclude/Extract/NonNullable というようにパターンごとに整理できると設計が一段と良くなります。
また、浅い操作が標準であることを忘れずに、ネストが深いデータ構造を扱う際には Deep系ユーティリティ型を構築したり、型推論制御を必要最低限に抑えたりすることでコードの可読性・型安全性を両立できます。
コメント