TypeScriptの「型パズル」を卒業しよう:PickとOmitでコードを美しく保つ技術
現場でコードを書いていると、「この巨大な型から、必要な3つのプロパティだけを取り出したい」とか、「DBから取得したオブジェクトから、IDだけ除いた更新用型を作りたい」といった場面に頻繁に出くわすはずです。
初心者のうちは、同じような型を何度も定義して、変更のたびに整合性が取れなくなって冷や汗をかく……なんてことも珍しくありません。今回は、そんな不毛な作業から卒業するための、`Pick`と`Omit`という「型操作の魔法」について、現場のリアルな視点から掘り下げていきます。
—
1. なぜ「型の再利用」がフロントエンドで重要なのか
まず前提として、TypeScriptの型はあくまで「コンパイル時のチェック」に使うもので、ブラウザが実行時にその型定義を読み取っているわけではありません。ブラウザ上のJSは、型が何であれ動くなら動いてしまいます。
しかし、「型がしっかりしている」ことは、開発者の未来の自分を守るための最強の防壁です。特にAPIレスポンスの型をそのままUIコンポーネントに流し込むような設計をしていると、APIの仕様変更で地獄を見ます。`Pick`や`Omit`を使って、必要な「断面」だけを切り出すことは、疎結合なアーキテクチャを作るための第一歩なんです。
—
2. Pick: 必要なものだけを「摘み取る」
`Pick
例えば、ユーザーのプロフィール情報が10個ほどある巨大な型から、ヘッダーに表示する「名前とアイコン画像」だけを抽出したいとき。これを使えば、元となる型を一切汚さずに新しい型を作れます。
type User = {
id: string;
name: string;
email: string;
avatarUrl: string;
bio: string;
createdAt: string;
// …あと数個続くとする
};
// 必要なプロパティだけをPickして「ヘッダー用型」を作成
type UserHeaderProfile = Pick
// これで、ヘッダーコンポーネントには最低限のデータしか渡されないことが保証される
const headerInfo: UserHeaderProfile = {
name: ‘田中太郎’,
avatarUrl: ‘https://example.com/icon.png’,
};
—
3. Omit: 不要なものを「削ぎ落とす」
`Omit
例えば、DBから取得する`User`型には`id`や`createdAt`が必須ですが、新しくユーザーを作成するAPIを叩く際、クライアント側でこれらのフィールドを送る必要はありません(むしろ送るとエラーになることも)。そんな時、`Omit`が輝きます。
// 作成用の型は、サーバーが生成するIDと日時を除外して作るのがセオリー
type CreateUserPayload = Omit
const newUser: CreateUserPayload = {
name: ‘佐藤花子’,
email: ‘hanako@example.com’,
avatarUrl: ‘…’,
bio: ‘フロントエンドエンジニアです。’,
};
—
4. 現場で使える「プロのTips」:型を合成する
ただ使うだけでなく、これらを組み合わせるのがシニアエンジニアの腕の見せ所です。
例えば、「既存のUser情報に、フォームの入力状態だけを追加したい」といった場面。`Pick`や`Omit`でベースを作り、それにインターセクション型(`&`)を組み合わせることで、型定義の重複をゼロにできます。
// 既存のUserから名前を除外し、そこに新しい「ニックネーム」を追加する
type UserSettings = Omit
nickname: string;
isSubscribed: boolean;
};
// これにより、User型の定義が変更されても、
// 必要な変更箇所を最小限に抑えることができる
最後に:型は「ドキュメント」である
`Pick`や`Omit`を多用しすぎると、たまに「型定義を追うのが大変だ」という声を聞くことがあります。確かにやりすぎは禁物ですが、「このコンポーネントは、大きな型の中の、この一部しか使っていない」という意図が型から読み取れることは、コードの保守性において非常に大きなメリットです。
型定義を「単なる制約」と捉えず、「このデータはどういう粒度で扱われるべきか」という設計思想の表明として使ってみてください。そうすれば、あなたのチームのコードは格段に読みやすく、そして強固なものになるはずです。
何か詰まったら、いつでもコードを見せてください。一緒にベストな型を模索しましょう。

コメント