TypeScriptのユーティリティ型は、既存の型から新しい型を組み込みで作り出すための道具です。種類が多く、似たような名前が並ぶため、いざ使おうとすると「今欲しいのはどれだっけ」と手が止まりがちです。

Partialとか Pickとか、名前は見るけど結局どれをいつ使えばいいの?
Pickと Omit、Excludeと Extract…似てて毎回どっちか分からなくなるんだよな。
組み込みに無い型変換がしたいとき、自作ってどう書けばいいんだ?

そこでこの記事では、頻出12個を1枚にまとめた早見表と「やりたいこと→使う型」の逆引きから入り、各型を最小コードで動かしながら使い分けを身につけます。最後には、ユーティリティ型の中身そのものである Mapped Types と Conditional Types を使った自作の入口まで踏み込むので、暗記に頼らず「必要なときに選べる」状態を目指せます。

この記事は次のような方におすすめです。

この記事はこんな人におすすめ!
  • Partialなどを実務で見かけるが、使い分けに自信がない方
  • Pick/Omit、Exclude/Extract の違いを毎回迷ってしまう方
  • 組み込みのユーティリティ型を一覧で整理したい中級者の方
  • 標準に無い型変換を自分で書けるようになりたい方

読み終えるころには、目の前の「型をこう変えたい」という要求に対して使うべき型が即座に思い浮かび、必要なら自作の型操作まで書けるようになります。

それでは、順を追って詳しく見ていきましょう!

ユーティリティ型とは何か(型から型を作る仕組み)

ユーティリティ型とは、既存の型を入力として受け取り、変換した別の型を返してくれる組み込みの型変換ツールです。PartialPickといった型は、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の出番です。

なかむぅ
なかむぅ
readonly修飾子そのものとReadonlyユーティリティ型の違いは、こちらでまとめて確認できます。
TypeScriptのreadonlyを完全理解|効かない罠と3つの書き分けTypeScriptのreadonlyを付けたはずなのに、いつの間にか値が書き換わっていた——そんな経験はありませんか? ...
なかむぅ
なかむぅ
Partialの使い分けをもっと掘り下げたい方は、こちらをどうぞ。
TypeScriptのPartial|効かない罠とRequiredの書き分けTypeScriptのPartialで全プロパティを任意化する基本から、ネストに効かない罠・型安全の落とし穴・対になるRequiredとの書き分けまで実コードで解説。更新処理やフォームで迷わず使えるようになります。...

キーで絞り込む型(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; }

PublicUserSafeUserは同じ結果ですが、片方は残すキーを、もう片方は除くキーを書いています。プロパティが多くて「ほとんど残す」なら 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を割り当てた型を作ります。辞書やマップのようなデータ構造の型付けに向いており、インデックスシグネチャを持つオブジェクト型と近い役割を担います。

なかむぅ
なかむぅ
Pickでキーを抽出するときの細かい挙動や応用は、こちらで詳しく解説しています。
【TypeScript】Pickでプロパティを抽出|Omitの使い分けと型再利用TypeScriptのPickは既存の型から必要なプロパティだけを抜き出すユーティリティ型です。基本の書き方からOmitとの使い分け、unionからの抽出、APIやフォームでの型再利用まで、実コードと型エラーつきで中級者向けに整理します。...
なかむぅ
なかむぅ
Omitで型からキーを除外する際の注意点は、こちらでまとめています。
【TypeScript】Omitを完全理解|Pickとの違いと3つの落とし穴TypeScriptのOmitでオブジェクト型から特定プロパティを除外する書き方を、Pickとの違いや実行時に効かない落とし穴、存在しないキー・union型での落とし穴まで実コードで解説します...
なかむぅ
なかむぅ
Recordとインデックスシグネチャの違いや使い分けは、こちらで詳しく解説しています。
TypeScriptのRecord型とインデックスシグネチャ(index signature)の違いTypeScriptのRecord型の使い方を、インデックスシグネチャ(index signature)との違いから整理。キー網羅の強制やundefinedの落とし穴、ユニオンキー・Partial併用まで実コードで解説し、型安全な設計に迷わなくなります。...

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の型情報を入力として渡しています。

実務での価値は、関数の引数や戻り値を変えても、それを参照する型が壊れずに追従することです。同じ型を別の場所で再宣言する重複を消せるため、定義のずれが起きにくくなります。

なかむぅ
なかむぅ
typeofやkeyofで既存の値・型から型を取り出す考え方は、こちらで体系的に解説しています。
TypeScriptのkeyofが分からない人向け|typeof併用まで完全理解TypeScriptのkeyofでオブジェクト型からキーの型を取り出す基本から、keyof typeofで値からキー型を作る書き方、ジェネリクスでの型安全なアクセス、any・配列・union型で挙動が変わる注意点までコード例で整理します。...

自作ユーティリティ型の作り方(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つの材料に行き着きます

なかむぅ
なかむぅ
inferで型を抽出する仕組みをもっと深く理解したい方は、こちらが参考になります。
TypeScriptのinferとは|型抽出の書き方を基礎から完全理解TypeScriptのinferを基礎から解説。Conditional Typesの仕組みからReturnTypeの分解、配列・Promiseの型抽出、つまずく罠までをtscの実出力付きで整理。自作の型ユーティリティが書けます。...

自作より組み込み・ライブラリを優先する判断基準

自作はあくまで最後の手段で、標準にある変換はまず標準を使うのが安全です。組み込みのユーティリティ型は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 で出来ており、無い変換は自作できる
  • 標準にあるものは標準を優先し、複雑な変換は既存ライブラリも検討する

「型をこう変えたい」という要求から逆引きできるようになれば、ユーティリティ型はもう迷う対象ではありません。 あとは手を動かしながら、必要に応じて自作まで広げていきましょう。

なかむぅ
なかむぅ
ユーティリティ型や自作の土台になるジェネリクス(generics)は、こちらで基礎から押さえられます。
【TypeScript】ジェネリクス(generics)完全理解|型引数Tと制約extendsの罠TypeScript genericsを基礎から実例で解説。型引数Tの書き方、複数引数、extendsによる制約、型推論の効かせ方、anyとの違いまで、tscの実出力つきで中級者のつまずきを整理します。...
なかむぅ
なかむぅ
自作の核になるinferで型を抽出する仕組みは、こちらで深掘りできます。
TypeScriptのinferとは|型抽出の書き方を基礎から完全理解TypeScriptのinferを基礎から解説。Conditional Typesの仕組みからReturnTypeの分解、配列・Promiseの型抽出、つまずく罠までをtscの実出力付きで整理。自作の型ユーティリティが書けます。...

※本記事の本文案はAIを活用して作成していますが、記載している内容およびコードは筆者が実際に調査、検証・実行し、内容の正確性を確認した上で公開しています。