【入門編】 PickとOmitを用いたPropsのフィルタリング – React実践ガイド

こんにちは!Reactの世界へようこそ。チーフアーキテクトの私です。

Reactを触り始めて、「あ、このコンポーネント、さっき作ったやつとほとんど同じなのに、一部のボタンだけ無くしたいな……」なんて壁にぶつかったことはありませんか?
「また一から同じような型を書かなきゃいけないの?」とため息をついたそこのあなた、大丈夫ですよ。今日はその面倒な作業を劇的に楽にしてくれる、TypeScriptの魔法の道具`Pick`と`Omit`についてお話ししますね。

これらを使いこなせるようになると、コードのコピペ地獄から抜け出し、まるでオーダーメイドの洋服を仕立てるかのようにスマートに型を組めるようになりますよ。

—

1. なぜPropsのフィルタリングが必要なの?(お買い物の例え)

突然ですが、街の洋服屋さんを想像してみてください。
そこには、とても便利な「万能ジャケット」が売っています。このジャケットには、以下の機能(Props)が全部ついているとしましょう。

  • 色 (`color`)
  • サイズ (`size`)
  • 価格 (`price`)
  • フードの有無 (`hasHood`)

さて、ここであなたのお店で「子ども用のフードなしパーカー」を新しく売り出すことになりました。
このとき、大人の万能ジャケットの設計図(型)をそのまま使ったらどうなるでしょう? 「フードの有無」なんて本当はいらないのに、無理やりつけなきゃいけなくなったり、余計なバグの温床になったりしますよね。

かといって、子ども用パーカーのためにゼロから設計図を書き直すのも、なんだかコードがもったいない(DRY原則に反する)気がしませんか?

そんなときに使うのが、既存の設計図から「ここだけ欲しい!」と摘み食いしたり、「ここは要らない!」と切り捨てたりできる`Pick`と`Omit`なんです。

—

2. 「Pick(ピック)」:欲しいものだけをスマートに摘み取る

まずは`Pick`から見ていきましょう。`Pick`は、英語の「摘み取る(ピックアップする)」のイメージそのままです。

既存の大きな型から、「このプロパティとこのプロパティだけが欲しい!」というときに使います。

コードで見てみよう

例えば、先ほどの万能ジャケットの型(Props)がこうあったとします。

// 元となる万能ジャケットの型
type JacketProps = {
color: string;
size: string;
price: number;
hasHood: boolean;
};

ここから、「色」と「サイズ」だけを厳選して使いたい!という新しいコンポーネントを作るとき、`Pick`はこう書きます。

// JacketProps から color と size だけを「摘み取る」
type SimpleJacketProps = Pick;

// 出来上がった SimpleJacketProps の中身は、実質こうなっています:
// {
// color: string;
// size: string;
// }

すごくスッキリしましたよね!「あれもこれも」と書く必要がなく、元の型が変わったときも自動で追従してくれるので、メンテナンス性も抜群に上がります。

—

3. 「Omit(オミット)」:いらないものをスパッと除外する

続いては`Omit`です。`Omit`は、「省く」「除外する」という意味を持っています。

こちらは、既存の型から「このプロパティ以外は全部使いたい!」という、引き算の考え方をする時に大活躍します。

コードで見てみよう

先ほどの万能ジャケットから、「価格(price)」だけを隠した(一般公開しない)スタッフ専用の表示用コンポーネントを作りたいとします。

そんなときは`Omit`の出番です。

// JacketProps から price だけを「除外する(取り除く)」
type StaffJacketProps = Omit;

// 出来上がった StaffJacketProps の中身は、実質こうなっています:
// {
// color: string;
// size: string;
// hasHood: boolean;
// }

「あれもこれも全部入れるけど、これだけは絶対に入れたくない!」という引き算の美学が、この`Omit`には詰まっています。既存のUIライブラリ(MUIやChakra UIなど)のボタンの型を拡張するときにも、この`Omit`は毎日のように実務で使いますよ。

—

4. 【実践】Reactコンポーネントでの具体的な使い方

では、実際にReactのコンポーネントの中でどうやってこれらが動くのか、コピペしてすぐに動かせるサンプルコードで確認してみましょう。

今回は、ボタンコンポーネントをベースにして、それを少し特殊なカード用のボタンにアレンジする例を考えてみます。

import React from ‘react’;

// 1. 基本となるボタンの型を定義します
type BaseButtonProps = {
label: string; // ボタンの文字(必須)
onClick: () => void; // クリックされた時の処理(必須)
backgroundColor: string; // 背景色(必須)
disabled: boolean; // 無効化フラグ(必須)
};

// 2. 「BaseButton」をそのまま定義
const BaseButton: React.FC = ({ label, onClick, backgroundColor, disabled }) => {
return (

);
};

// ==========================================
// ここからが Pick と Omit の本番です!
// ==========================================

// 3. 【Pickの例】
// カード用の特別なボタンを作ります。
//ここでは「label」と「onClick」の2つだけをBaseButtonから拝借(Pick)します。
// (背景色やdisabledはカード側で固定しちゃうので不要!)
type CardButtonProps = Pick;

const CardButton: React.FC = ({ label, onClick }) => {
return (

{/ 背景色はカード専用の色(#ff6b6b)に固定し、disabledは常にfalseにする /}

);
};

// 4. 【Omitの例】
// 管理画面用のボタンを作ります。
// これはBaseButtonの機能ほぼ全て欲しいけれど、「backgroundColor(背景色はシステム側で強制的に決まるため)」だけを除外(Omit)したい!
type AdminButtonProps = Omit;

const AdminButton: React.FC = ({ label, onClick, disabled }) => {
return (

);
};

このように、ベースとなるコンポーネントの型を軸にして、「足し算・引き算」感覚でスマートに派生型を作れるのが、`Pick`と`Omit`の最高に気持ちいいところです。

—

チーフアーキテクトからのアドバイス

実務でコードを書いていると、ついつい「めんどくさいから、新しい型を全部イチから書いちゃおう!」となりがちです。

ですが、それをやってしまうと、元のコンポーネントの仕様が変わったときに、あっちこッチの型を直す羽になり、バグの温床になってしまいます。「DRY(Don’t Repeat Yourself:同じことを何度も書かない)」の原則は、ロジックだけでなくTypeScriptの「型」の世界でも同じくらい大切です。

「あ、このProps、さっきのあいつとほとんど一緒だな」と思ったら、ぜひ一度立ち止まって、`Pick`や`Omit`でスマートに再利用できないか考えてみてください。あなたの書くReactコードが、ぐっと洗練されたプロの仕上がりになりますよ。

それでは、また次の現場でお会いしましょう!Happy Hacking!

コメント

タイトルとURLをコピーしました