TypeScriptのユーティリティ型一覧|頻出12個の使い分け早見表
TypeScriptのユーティリティ型は、既存の型から新しい型を組み込みで作り出すための道具です。種類が多く、似たような名前が並ぶため、いざ使おうとすると「今欲しいのはどれだっけ」と手が止まりがちです。
そこでこの記事では、頻出12個を1枚にまとめた早見表と「やりたいこと→使う型」の逆引きから入り、各型を最小コードで動かしながら使い分けを身につけます。最後には、ユーティリティ型の中身そのものである Mapped Types と Conditional Types を使った自作の入口まで踏み込むので、暗記に頼らず「必要なときに選べる」状態を目指せます。
この記事は次のような方におすすめです。
- Partialなどを実務で見かけるが、使い分けに自信がない方
- Pick/Omit、Exclude/Extract の違いを毎回迷ってしまう方
- 組み込みのユーティリティ型を一覧で整理したい中級者の方
- 標準に無い型変換を自分で書けるようになりたい方
読み終えるころには、目の前の「型をこう変えたい」という要求に対して使うべき型が即座に思い浮かび、必要なら自作の型操作まで書けるようになります。
それでは、順を追って詳しく見ていきましょう!
- 未経験で後悔したくない
【実体験】未経験からITエンジニアに転職して後悔した話|4社経験してわかった「最初の選択ミス」 - 年収が低くて不安
4年間ずっと年収260万だったエンジニアが、転職で510万になるまでの全記録
ユーティリティ型とは何か(型から型を作る仕組み)
ユーティリティ型とは、既存の型を入力として受け取り、変換した別の型を返してくれる組み込みの型変換ツールです。Partialや Pickといった型は、TypeScriptの標準ライブラリ(lib.es5.d.tsなどの定義ファイル)にあらかじめ用意されており、追加のインストールなしにそのまま使えます。
なぜ自分で型を書き直すより安全なのか。手書きで似た型を複製すると、元の型を変えたときに片方の修正を忘れ、定義がずれてしまいます。ユーティリティ型は元の型を参照して機械的に変換するため、元の型を変えれば派生した型も自動で追従し、重複と書き間違いが減ります。
type User = {
id: number;
name: string;
email: string;
};
// 素の手書き:Userを変えてもこちらは追従しない
type UserDraftManual = {
id?: number;
name?: string;
email?: string;
};
// ユーティリティ型:Userの変更に自動追従する
type UserDraft = Partial<User>;
// 結果の型: { id?: number; name?: string; email?: string; }
エディタ上で UserDraftにカーソルを合わせてホバーすると、Partial<User>を適用した結果として { id?: number; name?: string; email?: string; } が表示され、全プロパティが任意になっていることを確認できます。Userに項目を追加すれば UserDraftにも自動で反映されます。
この「型から型を作る」変換は魔法ではなく、内部は Mapped Types(既存のキーをまわして新しい型を組み立てる仕組み)と Conditional Types(型による条件分岐) という2つの機構で書かれています。この仕組みは記事後半の「自作ユーティリティ型の作り方」で実際に再現します。
ユーティリティ型 早見表(12個一覧)
実務でよく出会う組み込みユーティリティ型はおおむね12個に絞れます。まずは全体像を一覧で押さえ、細部は必要になったときに各章で確認すれば十分です。
| 型 | 用途(一言) | 型引数 | 対になる型 | 代表ユースケース |
|---|---|---|---|---|
| Partial | 全プロパティを任意化 | <T> |
Required | フォーム入力の途中状態 |
| Required | 全プロパティを必須化 | <T> |
Partial | 任意項目を埋め切った確定値 |
| Readonly | 全プロパティを読み取り専用化 | <T> |
(実質Partialと別軸) | 不変オブジェクトの保証 |
| Record | キー集合から型を生成 | <K, T> |
— | 辞書・マップ的なデータ |
| Pick | 指定キーだけ抽出 | <T, K> |
Omit | 一覧表示用の部分型 |
| Omit | 指定キーを除外 | <T, K> |
Pick | パスワードを除いた公開型 |
| Exclude | ユニオンからメンバー除外 | <T, U> |
Extract | 特定のリテラルを外す |
| Extract | ユニオンからメンバー抽出 | <T, U> |
Exclude | 共通部分だけ取り出す |
| NonNullable | null・undefinedを除去 | <T> |
— | 絞り込み後の確定型 |
| Parameters | 関数の引数型をタプルで取得 | <T> |
— | 引数型の再利用 |
| ReturnType | 関数の戻り値型を取得 | <T> |
— | 戻り値型の再利用 |
| Awaited | Promiseの解決後の型を取得 | <T> |
— | 非同期結果の型抽出 |
迷ったときは、暗記ではなく「やりたいこと」から逆引きすると速いです。
- プロパティの必須・任意・不変を切り替えたい → Partial/Required/Readonly
- 型から欲しいキーだけ/要らないキーを除いて使いたい → Pick/Omit
- キーと値の組み合わせから新しい型を作りたい → Record
- ユニオン型からメンバーを足し引きしたい → Exclude/Extract
- nullやundefinedを取り除きたい → NonNullable
- 既存の関数やPromiseから型を取り出したい → Parameters/ReturnType/Awaited
プロパティを書き換える型(Partial / Required / Readonly)
全プロパティの必須・任意・不変は、Partialで全任意化、Requiredで全必須化、Readonlyで再代入禁止に切り替えられます。いずれも元の型を1つ受け取り、プロパティの修飾だけを書き換えた型を返します。
type User = {
id: number;
name: string;
};
type A = Partial<User>;
// { id?: number; name?: string; }
type B = Required<Partial<User>>;
// { id: number; name: string; }(再び全必須に戻る)
const u: Readonly<User> = { id: 1, name: "Aki" };
u.id = 2; // 例:TS2540 Cannot assign to 'id' because it is a read-only property.
ここでの肝は、PartialとRequiredが互いに逆向きの変換だという対の関係です。元の型がすべて必須プロパティで構成されている場合は、Partialで任意化した型を Requiredで包むと全必須の形に戻せます。ただし、もともと任意だったプロパティの情報まで復元するわけではありません。一方 Readonlyは必須・任意とは別の軸で、値の再代入だけを禁止します。
注意したいのは、これらの変換が浅い(1階層だけの)変換だという点です。ネストしたオブジェクトの内側までは任意化されません。
type Profile = {
user: { id: number; name: string };
};
type P = Partial<Profile>;
// { user?: { id: number; name: string }; }
// user は任意になるが、その中の id・name は必須のまま
なお、ある1つのプロパティだけを任意にしたいなら型全体を Partialで包む必要はなく、そのプロパティに ?(オプショナル修飾)を付ければ済みます。全体を任意にしたいときが Partialの出番です。
キーで絞り込む型(Pick / Omit / Record)
型から必要なキーだけ取り出すなら Pick、要らないキーを除くなら Omit、キー集合と値の型から新しい型を作るなら Recordを使います。Pickは「残すキー」を、Omitは「捨てるキー」を指定する、という指定の向きの違いが要点です。
type User = {
id: number;
name: string;
password: string;
};
type PublicUser = Pick<User, "id" | "name">;
// { id: number; name: string; }
type SafeUser = Omit<User, "password">;
// { id: number; name: string; }
type RoleFlags = Record<"admin" | "guest", boolean>;
// { admin: boolean; guest: boolean; }
PublicUserと SafeUserは同じ結果ですが、片方は残すキーを、もう片方は除くキーを書いています。プロパティが多くて「ほとんど残す」なら Omit、「少しだけ使う」なら Pick と選ぶと記述量を抑えられます。
| やりたいこと | 書き方(Pick基準) | 書き方(Omit基準) |
|---|---|---|
| name だけ使う | Pick<User, "name"> |
Omit<User, "id" | "password"> |
| password を隠す | Pick<User, "id" | "name"> |
Omit<User, "password"> |
Pickは存在しないキーを指定すると、その場でエラーになります。
type Broken = Pick<User, "age">;
// 例:TS2344 Type '"age"' does not satisfy the constraint 'keyof User'.
Record<K, T>は、キーの集合 Kそれぞれに同じ値の型 Tを割り当てた型を作ります。辞書やマップのようなデータ構造の型付けに向いており、インデックスシグネチャを持つオブジェクト型と近い役割を担います。
union を操作する型(Exclude / Extract / NonNullable)
ユニオン型からメンバーを除くなら Exclude、特定のメンバーだけ取り出すなら Extract、nullとundefinedを取り除くなら NonNullableを使います。これらはオブジェクト型ではなくユニオン型のメンバーを足し引きする道具だ、という点がPick/Omitとの決定的な違いです。
type Color = "red" | "green" | "blue";
type WithoutBlue = Exclude<Color, "blue">;
// "red" | "green"
type OnlyGreen = Extract<Color, "green" | "yellow">;
// "green"(両方に含まれるメンバーだけ残る)
type MaybeName = string | null | undefined;
type Name = NonNullable<MaybeName>;
// string
混同しやすいのが、Pick/OmitとExclude/Extractの守備範囲です。前者はオブジェクト型のキーを操作し、後者はユニオン型のメンバーを操作します。対象が「キー」か「メンバー」かで、見分けが付きます。
| 操作対象 | 抜き出す | 取り除く |
|---|---|---|
| オブジェクト型のキー | Pick | Omit |
| ユニオン型のメンバー | Extract | Exclude |
この対応を取り違えると、たとえばユニオンに対してキー操作の型を使ってしまい、想定したメンバーが残らずに型が食い違います。「キーならPick/Omit、メンバーならExtract/Exclude」と対象から逆引きすると間違えにくくなります。
関数から型を取り出す型(Parameters / ReturnType / Awaited)
既存の関数やPromiseから型を再利用するなら、引数の型は Parameters、戻り値の型は ReturnType、Promiseの解決後の型は Awaited で取り出せます。型を手書きで複製せずに済むため、関数のシグネチャ変更に型が自動で追従します。
function createUser(id: number, name: string) {
return { id, name, createdAt: new Date() };
}
type Args = Parameters<typeof createUser>;
// [id: number, name: string]
type Result = ReturnType<typeof createUser>;
// { id: number; name: string; createdAt: Date; }
type Resolved = Awaited<Promise<string>>;
// string
これらの型に渡しているのは値ではなく型なので、関数そのものから型を取り出す typeofを併用するのがポイントです。Parameters<typeof createUser>のように書くことで、createUserの型情報を入力として渡しています。
実務での価値は、関数の引数や戻り値を変えても、それを参照する型が壊れずに追従することです。同じ型を別の場所で再宣言する重複を消せるため、定義のずれが起きにくくなります。
自作ユーティリティ型の作り方(Mapped Types と Conditional Types)
組み込みに無い変換が欲しいときは、Mapped Types と Conditional Types を使えば自分でユーティリティ型を作れます。実は標準の Partialなども、これらの機構で書かれています。
まず Partial相当を Mapped Types で再現してみます。[K in keyof T]で元の型 Tのキーをすべてまわし、各プロパティに ?を付けて任意化します。
type MyPartial<T> = { [K in keyof T]?: T[K] };
type User = { id: number; name: string };
type A = MyPartial<User>;
// { id?: number; name?: string; }(標準 Partial<User> と同じ結果)
次に Conditional Types です。T extends U ? X : Yという形で、型が条件を満たすかどうかで返す型を分岐できます。inferを組み合わせると、条件にマッチした部分の型を取り出せます。
type ElementType<T> = T extends (infer U)[] ? U : T;
type A = ElementType<string[]>;
// string(配列なら要素の型を取り出す)
type B = ElementType<number>;
// number(配列でなければそのまま返す)
この2機構こそ、記事冒頭で触れた「ユーティリティ型の内部はMapped TypesとConditional Typesで出来ている」の正体です。完成品の道具(ユーティリティ型)を分解すると、この2つの材料に行き着きます。
自作より組み込み・ライブラリを優先する判断基準
自作はあくまで最後の手段で、標準にある変換はまず標準を使うのが安全です。組み込みのユーティリティ型はTypeScript本体でメンテナンスされ、エッジケースも踏まれているため、車輪の再発明を避けられます。
判断の目安は次のとおりです。
- 標準に同等のものがある → 標準をそのまま使う
- 標準に無いが単純な変換 → Mapped/Conditional Types で自作する
- 複雑・再帰的で可読性やメンテ性が下がる → type-fest などの既存ライブラリ採用も検討する
自作の型は、特に分配的条件型(ユニオンに対して条件型が各メンバーへ分配される挙動)などで直感に反する結果になりやすく、注意が要ります(具体的な挙動はTypeScriptのバージョンや書き方により異なる場合があり、Playgroundでの確認が確実です)。複雑な変換ほど、まず既存の解がないかを探すと安全に進められます。
よくある質問
Q1. Mapped Types・Conditional Types とユーティリティ型は何が違う
ユーティリティ型は すぐ使える完成品の道具で、Mapped Types と Conditional Types はその道具を作るための材料です。Partialなどの中身はこの2機構で書かれており、組み込みで足りなければ同じ材料で自作できます。両者は別物ではなく、抽象度の違う関係だと捉えると整理できます。
Q2. Pick と Omit、Exclude と Extract はどう使い分ける
判断軸は操作する対象です。PickとOmitはオブジェクト型のキーを抜く/除く道具、ExcludeとExtractはユニオン型のメンバーを除く/取り出す道具です。「キーならPick/Omit、メンバーならExtract/Exclude」と対象から逆引きすれば、名前を覚えていなくても即座に選べます。
Q3. Partial を使ったらネストしたプロパティが任意にならないのはなぜ
標準の Partial は浅い(1階層だけの)変換だからです。Partialは最上位のプロパティを任意化しますが、その内側のオブジェクトには再帰的に適用されません。ネストの奥まで任意化したい場合は、Mapped Types を再帰的に書いた自作の型が必要になります(挙動はバージョンにより異なる場合があります)。
Q4. ユーティリティ型は全部覚える必要がある
覚える必要はありません。頻出12個を早見表で押さえ、残りは「やりたいこと→使う型」で都度逆引きすれば実務は回ります。よく使う型は手を動かすうちに自然と定着するので、最初から全暗記を目指すより、逆引きできる状態を作るほうが現実的です。
【付録】さらに学びを深めるためのリソース
さらにTypescriptの学習を進めたい方のために、いくつかのリソースを紹介します。
これらのリソースを活用することで、TypeScriptの型システムについてより深い知識を得ることができるでしょう。
おすすめの書籍
ゼロからわかる TypeScript入門
技術評論社から出版されている「ゼロからわかる TypeScript入門」は、プログラミング初心者や本職プログラマーではない方を主な対象にした入門書です。
変数・条件分岐・ループといった基本から、クラスやインターフェース、モジュールまで段階的に学べる構成になっています。最終章ではWeb APIとJSONを使った非同期Webアプリの作成も体験できるので、「実際に動くものを作る」ところまで到達できます。
プロを目指す人のためのTypeScript入門
技術評論社の「プロを目指す人のためのTypeScript入門 安全なコードの書き方から高度な型の使い方まで」、通称 ブルーベリー本 です。
JavaScriptの仕様とTypeScript独自の機能を両方押さえつつ、リテラル型・ユニオン型・keyof型・ジェネリクスなど、高度な型表現まで踏み込んで解説しています。TypeScriptの型システムの表現力を本格的に学べる一冊です。
オンラインで参照できる公式ドキュメント
TypeScript公式ハンドブック
https://www.typescriptlang.org/docs/
TypeScriptの公式ドキュメントです。
intersection型を含む、すべての型システムの機能について詳細な説明があります。
TypeScript Deep Dive
https://basarat.gitbook.io/typescript/
TypeScriptの深い部分まで掘り下げて解説しているオンラインブックです。
無料で読むことができ、intersection型についても詳しく説明されています。
TypeScriptの学習は終わりがありません。
新しい機能が常に追加され、より良い書き方が発見されています。
継続的に学習を続けることで、より良いTypeScriptプログラマーになれるはずです。
まとめ – 逆引きで選べば暗記不要のユーティリティ型
この記事のポイントをまとめます。
- ユーティリティ型は既存の型から新しい型を組み込みで作る道具で、重複と書き間違いを減らせる
- 頻出12個は「やりたいこと→使う型」の逆引きで選べば、丸暗記は不要
- Pick/Omitはオブジェクト型のキー操作、Exclude/Extractはユニオン型のメンバー操作と対象で見分ける
- ユーティリティ型の中身は Mapped Types と Conditional Types で出来ており、無い変換は自作できる
- 標準にあるものは標準を優先し、複雑な変換は既存ライブラリも検討する
「型をこう変えたい」という要求から逆引きできるようになれば、ユーティリティ型はもう迷う対象ではありません。 あとは手を動かしながら、必要に応じて自作まで広げていきましょう。
※本記事の本文案はAIを活用して作成していますが、記載している内容およびコードは筆者が実際に調査、検証・実行し、内容の正確性を確認した上で公開しています。






