【実務・中級編】 TypeScriptによるPropsのインターフェース定義 – React実践ガイド

React × TypeScript:型定義という名の「信頼」をコードに刻む

やあ。現場でコードを書いていて、「このProps、結局何が渡されるのか実行してみないとわからない」という恐怖に震えたことはないかい?

Reactの柔軟性は諸刃の剣だ。Propsを適当に渡しても動いてしまうからこそ、数ヶ月後の自分やチームメンバーが「このバグ、どこで混入したんだ?」と頭を抱えることになる。

今回は、TypeScriptを使ってコンポーネントに堅牢な「型」を定義し、開発体験(DX)と保守性を極限まで高める方法を伝授する。公式ドキュメントに書いてあるような浅い話は飛ばす。現場で泥臭く戦う君たちに必要な「本質」を話そう。

—

1. なぜ「インターフェース」で定義するのか

まず、ブラウザの視点に立ってみよう。ブラウザはTypeScriptなんて知らない。最終的にJavaScriptにトランスパイルされ、Reactはそれを仮想DOMとして処理する。

重要なのは、「型定義はブラウザのためではなく、未来の君とチームのために存在する」という点だ。

`any`を使えば一瞬でエラーは消えるが、それは「安全装置を外して時速200kmで走る」のと同じだ。Propsのインターフェースを定義することは、コンポーネントに対する「契約書」を作成することに他ならない。

2. 実践的なインターフェース定義のベストプラクティス

現場でよく見る「とりあえず全部オプショナル(`?`)」にする悪癖は今すぐ捨てよう。必要なものは必要、ないものは定義しない。これが鉄則だ。

以下は、実務で頻出するパターンを網羅したコード例だ。

import React from ‘react’;

/

  • 現場でよく使うProps定義のテンプレート
  • 1. 必須なものはそのまま、任意なものは ? をつける
  • 2. 変更不可なデータには readonly をつけることで意図せぬミューテーションを防ぐ

/
interface ButtonProps {
readonly label: string;
readonly onClick: () => void;
// 任意プロパティ:あってもなくても良いもの
readonly variant?: ‘primary’ | ‘secondary’ | ‘danger’;
// 子要素を受け取る場合は React.ReactNode を使うのが定石
readonly children?: React.ReactNode;
}

export const Button: React.FC = ({
label,
onClick,
variant = ‘primary’, // デフォルト値の設定
children
}) => {
return (

);
};

3. ここがプロのポイント:`React.FC`を使うべきか否か

最近のReact界隈で議論になるのが、「`React.FC`を明示的に使うべきか、単なる関数として書くべきか」という点だ。

僕個人の見解としては、「`React.FC`は使わなくていい(または最小限でいい)」派だ。

理由は単純。`React.FC`を使うと、`children`が暗黙的に含まれてしまうからだ。「このコンポーネントは子要素を受け取らないはずなのに、なぜか渡せてしまう」という微妙な型安全性の崩壊を招くことがある。

以下のように、関数の引数に直接型を当てるスタイルの方が、現代的でモダンだ。

// 冗長なReact.FCを廃し、よりピュアに定義するスタイル
interface CardProps {
readonly title: string;
}

export const Card = ({ title }: CardProps) => {
return

{title}

;
};

これなら、`children`を渡そうとすればTypeScriptが即座に「そんなプロパティはない」と怒ってくれる。この「厳しい指摘」こそが、デバッグ時間を削減する最大の武器になるんだ。

4. 最後に:型は「ドキュメント」である

コードを書くとき、型定義を「面倒な作業」だと思っていないか?
それは間違いだ。型定義は、コードの読み手に対する最強のドキュメントだ。

IDEのホバー機能で型が表示されるとき、そこに適切な型が定義されていれば、ドキュメントを読みに行かずともそのコンポーネントの使い方がわかる。これがチーム開発における「摩擦」を減らす。

  • インターフェースは小さく分割する(巨大なPropsオブジェクトを作らない)
  • `type`ではなく`interface`を優先する(宣言的マージが可能で拡張性が高いため)
  • 「とりあえずany」は禁句にする(それを打った瞬間に、君のコードの寿命は縮まる)

この3つを意識するだけで、君の書くコードは驚くほど洗練されるはずだ。

Reactは自由だ。その自由を「無法地帯」にするのか、「規律ある表現の場」にするのか。それは、君が今書いているその数行の型定義にかかっている。頑張ってくれ、期待しているよ。

コメント

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