こんにちは!Reactの学習、楽しく進められていますか?
画面にボタンを表示して、クリックしたら文字が変わって……という感動を味わったあとに、ふとこんな疑問が湧いてきませんでしたか?
「あれ? コンポーネントにデータを渡すときの型定義、`interface` と `type` って、どっちを使えばいいんだろう……?」
ネットで調べると、「基本はどっちでもいいよ」なんて書いてあったりして、「いやいや、初心者の私にはその『どっちでもいい』が一番悩ましいんだよ!」ってツッコミたくなりますよね。安心してください、その悩み、誰もが通るすごくまっとうな道です。
今回は、現場の第一線で毎日Reactを書いている私から、この `interface` と `type` の迷いをスッキリ解消するための「使い分けのコツ」を、身近な例えを交えながらお話ししていきますね。
—
そもそも `interface` と `type` って何をしているの?
Reactでコンポーネントを作るとき、親から子へデータを渡す「Props(プロップス)」という仕組みを使いますよね。このPropsが「どんなデータを受け取るべきか」をTypeScriptに教えるための看板が、`interface` や `type` です。
イメージとしてはそうですね、「カフェの注文書」みたいなものです。
- 「ドリンクの種類は必須、サイズは選べる、カスタムシロップは任意」
- この注文書ルールをパッと見てわかるように定義するのが、型定義の役割です。
そして、この注文書を作るための文房具として用意されているのが、`interface` と `type` なんです。
—
身近な例えで違いを知ろう
では、この2つの文房具、何が違うのでしょうか?
身近なもので例えてみましょう。
1. `interface`(インターフェース)=「後から継ぎ足せる、システムキッチンのパーツ」
`interface` は、あとから同じ名前で定義を追加(マージと言います)することができます。
- 例え: 最初は「コンロ」と「シンク」だけだったシステムキッチンに、あとから「食洗機」のパーツをドッキングさせるようなイメージです。
- 特徴: オブジェクトの形を定義するのが得意。後から拡張されることを前提とした作り方に強いです。
2. `type`(タイプ)=「なんでも作れる、レゴブロックの設計図」
`type` は、名前の通りデータに「型番(名前)」を貼るものです。オブジェクトだけでなく、文字列を限定したり(例:「赤」か「青」しか選べないなど)、複雑な組み合わせができます。
- 例え: レゴブロックの設計図です。動物を作ったり、乗り物を作ったり、あるいは「このブロックとこのブロックを合体させた新しいブロックセット」を作ったりと、自由自在です。
- 特徴: 柔軟性が高く、何でもできるオールラウンダー。
—
初学者のための「迷わない使い分け基準」
結論から言いましょう。ReactのコンポーネントでPropsを定義するとき、現場で私たちがどう使い分けているかというと、基本ルールはこれだけです。
1. 基本は `interface` を使っておけば間違いない!
2. 特殊なこと(ユニオン型など)をしたいときだけ `type` を使う!
これだけだと少し抽象的なので、もう少し具体的に見ていきましょう。
理由:ReactのコンポーネントのPropsは「オブジェクト」だから
ReactのPropsは、ほぼ100%「こういう形のデータを受け取りますよ」というオブジェクトです。オブジェクトの形を綺麗に、分かりやすく表現する能力において、`interface` は非常に優れています。エラーメッセージも親切に出してくれます。
だから、特別な理由がない限りは `interface` を選んでおけば、初学者のうちはまず困りません。「迷ったら `interface`!」と覚えておいてくださいね。
—
実例で見てみよう!コードで確認する使い方
百聞は一見にしかず。実際のReactコンポーネントでどう書くのか、お寿司屋さんのメニューカードを例に見てみましょう。
パターンA:基本の `interface`(おすすめ!)
お皿の色と、お寿司の名前を受け取るシンプルなカードコンポーネントです。
import React from ‘react’;
// 1. Propsの型定義を interface で行います
// (オブジェクトの形を定義するときはこれが一番スッキリします)
interface SushiCardProps {
sushiName: string; // お寿司の名前(文字列)
price: number; // お値段(数値)
isRecommended?: boolean; // おすすめかどうか(真偽値・?をつけると「なくてもOK」になります)
}
// 2. コンポーネントに型を適用します
export const SushiCard: React.FC
sushiName,
price,
isRecommended = false // デフォルト値の設定
}) => {
return (
{isRecommended && 【推し!】}
{sushiName}
{price}円
);
};
どうでしょう? `interface` を使うことで、「あ、このコンポーネントにはこういうデータを渡せばいいんだな」というのが一目で分かりますよね。
パターンB:`type` を使うべきケース
では、逆に `type` を使わざるを得ない、あるいは `type` の方が圧倒的に便利なのはどんなときでしょうか?
それは、「選べる値を制限したいとき(ユニオン型)」や「既存の型を合体させたいとき」です。
import React from ‘react’;
// ステータスを「loading」「success」「error」のどれかに限定したい!
// こういう「特定の文字しか受け付けない」という定義は type の得意分野です。
type FetchStatus = ‘loading’ | ‘success’ | ‘error’;
interface StatusBannerProps {
status: FetchStatus;
message: string;
}
export const StatusBanner: React.FC
return (
現在の状態: {status}
{message}
);
};
このように、データの形だけでなく「選択肢を絞りたい!」というときは `type` の出番です。
—
つまずきやすいポイントと温かいアドバイス
ReactとTypeScriptを学び始めの頃は、赤色の波線エラー(型エラー)が出ると、まるで自分が怒られているような気持ちになって手が止まってしまうこと、ありますよね。
「Property ‘sushiName’ is missing in type…(このプロパティ足りないよ!)」なんて言われると、冷や汗が出てしまいます。
でも、大丈夫ですよ。
そのエラーは、TypeScriptという優しい相棒が、「ねえ、親御さんから渡してもらうはずの大事なデータが抜けてるよ! 画面が真っ白になっちゃう前に教えてあげるね!」と、事前に教えてくれているラブレターのようなものです。
最初はエラーにビクビクするかもしれませんが、`interface` や `type` をしっかり書いておくことで、エディタ(VSCodeなど)が自動補完で「次はこれを入れるんだよ」と教えてくれるようになります。コーディングが驚くほど快適になりますよ。
—
まとめ
最後に、今日のお話をギュッとまとめますね。
- 迷ったら `interface` を使おう!(オブジェクトの型定義に一番向いているため)
- 文字の選択肢を縛りたいときや、複雑な組み合わせをしたいときは `type` を使おう!
- 型定義はあなたを縛る鎖ではなく、コードの安全を守り、開発を助けてくれる「最高の設計図」です。
最初は難しく感じるかもしれませんが、手を動かしていくうちに「あ、ここは `interface` がしっくりくるな」と体で分かってきます。焦らず、自分のペースで楽しくReactを書いていきましょう!
あなたのフロントエンド開発の旅を、心から応援しています!

コメント