なぜReactにTypeScriptを使うのか
TypeScriptを導入することで「コンパイル時にバグを検出できる」「IDEの補完が充実する」「チーム開発でのコードの意図が明確になる」という3つの大きな恩恵を受けられます。2025年現在、ReactプロジェクトのTypeScript採用率は80%を超えており、新規プロジェクトではTypeScript使用がほぼデフォルトとなっています。求人票でも「React/TypeScript必須」という記載が急増しています。
TypeScriptの最大の恩恵は「IDEの補完強化」です。プロパティ名のタイポがビルド前にエラーとして検出され、関数の引数・返り値の型が明確になることでコードが自己文書化されます。チーム開発では特にこの恩恵が大きく、コードレビューの負担が大幅に減ります。
- 採用率の現状:2025年のReactプロジェクトの80%以上がTypeScriptを採用
- 求人市場の評価:「React/TypeScript必須」求人が「React(JS)のみ」求人を大幅に上回る
- 学習コスト:JavaScript経験者なら1〜2週間で基本的な型定義をマスターできる
- 長期的な価値:大規模コードベースでの保守性・可読性が格段に向上する
Propsの型定義パターン
Reactコンポーネントのpropsはinterfaceまたはtype aliasで定義します。interface ButtonProps { label: string; onClick: () => void; variant?: 'primary' | 'secondary'; }のように必須・オプショナルを明示できます。ChildrenをPropsに含める場合はReact.ReactNode型を使います。型定義をコンポーネントと同じファイルに書くか、types.tsに集約するかはプロジェクト規模に応じて決めましょう。
- interfaceによるProps定義:
interface ButtonProps { label: string; onClick: () => void; } - オプショナルプロパティ:
variant?: 'primary' | 'secondary'(?で省略可能を表現) - Children型:
children: React.ReactNode(JSXを含む任意の型を受け付ける) - ユニオン型:
status: 'loading' | 'success' | 'error'で状態を型安全に管理
useState・useRefの型指定
フックの型指定はuseState<number>(0)のようにジェネリクスで指定します。初期値から推論できる場合は省略可能ですが、nullを初期値にする場合はuseState<User | null>(null)と明示が必要です。useRefでDOM参照する場合はuseRef<HTMLInputElement>(null)と要素の型を指定します。これにより.currentで取得した値が適切な型で補完されます。
- 基本的なuseState:
const [count, setCount] = useState<number>(0) - nullを含む場合:
const [user, setUser] = useState<User | null>(null) - DOM参照のuseRef:
const inputRef = useRef<HTMLInputElement>(null) - 型推論の活用:初期値から型が明確な場合はジェネリクスを省略できる
カスタムフックの型設計
カスタムフックは返り値の型を明示することでAPIが明確になります。function useFetch<T>(url: string): { data: T | null; loading: boolean; error: string | null }のようにジェネリクスを使うと、呼び出し元で具体的な型を指定でき再利用性が高まります。カスタムフック内部でuseCallbackやuseEffectを使う場合も、依存配列の型エラーをTypeScriptが検出してくれます。
- ジェネリクスの活用:
useFetch<User[]>('/api/users')でデータの型を指定できる再利用可能なフック - 返り値の明示:タプル型またはオブジェクト型で返り値を明示するとAPIが分かりやすくなる
- 型の一貫性:カスタムフック内で使うuseCallbackの依存配列の型チェックも自動で行われる
よくあるTypeScriptエラーとその解決法
初心者が詰まりやすいエラーとして「Object is possibly undefined」はオプショナルチェーン(?.)やnullチェックで解決、「Type 'string' is not assignable to type 'number'」は型変換(Number()・parseInt())で解決、「Property does not exist on type」はinterfaceへのプロパティ追加またはtypeofガードで解決します。エラーメッセージを読んで型を追いかけていく習慣が最短上達の近道です。
- 「Object is possibly undefined」:オプショナルチェーン(
obj?.property)またはnullチェック(if (obj))で対処 - 「Type 'string' is not assignable to type 'number'」:型変換(
Number(str)・parseInt(str))で対処 - 「Property does not exist on type」:interfaceへのプロパティ追加またはindex signature(
[key: string]: any)で対処 - 「Cannot find module」:型定義ファイル(@types/パッケージ名)のインストールで対処
TypeScript×Reactの学習ロードマップ
習得の順序は「①JavaScript基礎 → ②React基礎(useState/useEffect)→ ③TypeScript基礎(型・インターフェース・ジェネリクス)→ ④React×TypeScript統合」が理想的です。TypeScriptのHandbookとReact公式ドキュメントのTypeScriptセクションは必読です。実践では小さなコンポーネントから型を付けていく習慣を積み上げることが最も効果的です。
- STEP1(1〜2ヶ月):JavaScript基礎→React基礎(useState・useEffect・コンポーネント設計)
- STEP2(2〜4週間):TypeScript基礎(型・インターフェース・ジェネリクス・ユニオン型)
- STEP3(1ヶ月):React×TypeScriptの統合(Props型定義・フックの型指定・カスタムフック)
- STEP4(継続):実際のプロジェクトでJavaScriptコードにTypeScriptを徐々に適用していく