React×TypeScriptの「型泥沼」から脱却せよ:PickとOmitでPropsを自在に操る極意
フロントエンドの現場で「Propsの型定義、面倒くさいな」と感じたことはないだろうか?
コンポーネントが肥大化し、似たようなPropsを何度も定義し直し、挙句の果てに「変更のたびに3箇所で型を書き換える」という地獄のようなメンテナンス作業。もし心当たりがあるなら、それはTypeScriptのユーティリティ型を使いこなせていない証拠だ。
今日は、Reactの実務において「型を正しく、かつ楽に」管理するための、`Pick`と`Omit`の使いこなし術について話そう。これは単なる型テクニックではない。「コンポーネントの責務をどう切り分けるか」というアーキテクチャそのものの話だ。
—
なぜ、わざわざ型を操作するのか?
結論から言えば、「DRY(Don’t Repeat Yourself)原則を型にまで適用するため」だ。
例えば、ユーザー情報を表示する `UserCard` があり、その中にボタンがあるとする。ボタンが受け取るPropsが `User` 型の全要素を必要としていないなら、そのまま渡すのは「情報の漏洩」であり、依存関係を不必要に強めてしまう。
ブラウザの裏側でコンポーネントがどう動くかを考えれば、Propsは「コンポーネントが最低限必要なインターフェース」であるべきだ。ここを整理するだけで、レンダリングの最適化や、コンポーネントの再利用性が劇的に向上する。
—
実践:PickとOmitの使い分け
まずは、ベースとなるProps定義を一つ用意しよう。
// 現場でよくある巨大な型定義
type UserProfile = {
id: string;
name: string;
email: string;
bio: string;
isAdmin: boolean;
lastLogin: Date;
};
1. Pick:必要なものだけを「摘み取る」
「このコンポーネントには名前とプロフィール文さえあればいい」という時は `Pick` を使う。
// UserProfileから必要なプロパティだけを抜き出す
type UserBioProps = Pick
const UserBio: React.FC
{name}
{bio}
);
2. Omit:不要なものを「削ぎ落とす」
逆に、「管理者権限やログイン情報は渡したくない」という時は `Omit` が最強だ。
// UserProfileからisAdminとlastLoginを除外した型を作成
type PublicUserProps = Omit
const UserDisplay: React.FC
// propsにはid, name, email, bioのみが含まれる
return
;
};
—
現場で「膝を打つ」ための応用テクニック
ここからが本題だ。中級者から一歩先へ行くための、現場で使えるプロのTipsを紹介する。
`ComponentProps` との組み合わせ
既存のライブラリのコンポーネントをラップする場合、全てを一から書くのは無駄だ。
import { ComponentProps } from ‘react’;
// Buttonコンポーネントから ‘onClick’ だけを除外して独自のボタンを作る例
type CustomButtonProps = Omit
onCustomClick: () => void;
};
export const CustomButton = ({ onCustomClick, …rest }: CustomButtonProps) => {
return ;
};
こうすることで、HTMLの `button` 要素が持つ本来の属性(`type`, `disabled`など)を型安全に継承しつつ、独自のインターフェースだけを強制できる。これが「型によるカプセル化」だ。
—
シニアからのアドバイス:型は「ドキュメント」である
最後に一つだけ覚えて帰ってほしい。「型は単なるチェックツールではなく、コンポーネントの仕様書だ」ということだ。
`Pick` や `Omit` を多用しすぎると、型定義を追うのが難しくなるという側面もある。しかし、何でもかんでもインターフェースを分けて定義し直すより、元の型から「何が不要で、何が必要か」を明示する方が、後の開発者がコードを読んだ時の意図(「あ、ここはプロフィール情報しか使わないんだな」)が明確に伝わる。
ReactのPropsは、コンポーネントという「関数」への引数だ。その引数が適切に制限されていれば、予期せぬバグは減り、変更への耐性は高まる。
今日のコードを明日からの開発に持ち込んでみてくれ。もしチームメンバーに「なぜここでOmitを使っているの?」と聞かれたら、胸を張ってこう答えてやればいい。
「このコンポーネントの責務を、型レベルで最小化するためだよ」と。
コードを書くことは、コミュニケーションだ。型という言語を使って、最高のチームを作っていこうぜ。

コメント