環境構築
TypeScript + React の開発環境をセットアップします
このチャプターで学ぶこと
- TypeScriptとは何かを理解できる
- Vite + React + TypeScript のプロジェクトを作成できる
- tsconfig.json の基本設定を理解できる
- .ts と .tsx の違いを理解できる
環境構築
Reactコースを終えた皆さん、お疲れさまでした。ここからは TypeScript を導入して、より安全で快適な React 開発を目指しましょう。Laravel や Rails でバックエンド開発をしてきた方なら、「型がある」ことの安心感はすでにご存じのはずです。PHP の型宣言や Ruby の Sorbet/RBS に近い感覚で、JavaScript に型を追加できるのが TypeScript です。
TypeScript とは何か
TypeScript は Microsoft が開発した、JavaScript に 静的型付け を追加した言語です。拡張子は .ts(JSXを含む場合は .tsx)で、最終的にはすべて JavaScript にコンパイルされてからブラウザで実行されます。
// JavaScript(型がない)
function greet(name) {
return `こんにちは、${name}さん!`;
}
// TypeScript(型がある)
function greet(name: string): string {
return `こんにちは、${name}さん!`;
}
TypeScript のコードは直接ブラウザでは動きません。ビルド時に JavaScript に変換(トランスパイル)されます。この工程は Vite が自動でやってくれるので、開発者が手動で変換する必要はありません。
Laravel で例えるなら、Blade テンプレートが最終的に PHP コードに変換されるのと同じ発想です。開発者は便利な構文で書き、ツールが実行可能な形に変換してくれます。
なぜ TypeScript を使うのか
TypeScript を導入する理由は主に3つあります。
1. 型安全性 — バグを未然に防ぐ
// JavaScript: 実行するまでバグに気づけない
function calculateTotal(price, quantity) {
return price * quantity;
}
calculateTotal("1000", 3); // "100010001000" — 文字列が繰り返される!
// TypeScript: コードを書いた瞬間にエラーが出る
function calculateTotal(price: number, quantity: number): number {
return price * quantity;
}
calculateTotal("1000", 3); // コンパイルエラー:string は number に代入できません
PHP でも declare(strict_types=1) を書いて型の厳格チェックを有効にしますよね。TypeScript はそれをさらに徹底したものだと考えてください。
2. IDEサポート — 開発速度の向上
型情報があると、VS Code などのエディタが強力な補完や候補を出してくれます。
- プロパティ名の自動補完
- 関数の引数の型や戻り値の表示
- 使われていない変数の警告
- リファクタリング時の安全な一括変更
Laravel で PHPStan や IDE Helper を使っている方は、その恩恵をさらに強くしたものだと想像してください。
3. チーム開発 — コードが仕様書になる
// 型定義がそのままインターフェースの仕様書になる
interface User {
id: number;
name: string;
email: string;
role: "admin" | "editor" | "viewer";
}
型定義を見れば、データの構造やとりうる値が一目で分かります。Laravel の Migration がテーブル構造のドキュメントになるように、TypeScript の型定義はAPIレスポンスやコンポーネントの props の仕様書になります。
TypeScript は「厳しい JavaScript」ではなく「親切な JavaScript」です。エラーメッセージは「ここが間違っているよ」と具体的に教えてくれるので、デバッグ時間が大幅に短縮されます。
Vite + React + TypeScript のプロジェクトを作成する
React コースでは --template react を使いましたが、TypeScript 版は --template react-ts を指定します。
npm create vite@latest my-ts-app -- --template react-ts
作成されたら、おなじみの手順でセットアップします。
cd my-ts-app
npm install
npm run dev
これだけで TypeScript 対応の React プロジェクトが完成します。
既存の React(JavaScript)プロジェクトに TypeScript を後から追加することもできますが、最初から react-ts テンプレートを使うほうが圧倒的に楽です。設定ファイルや型定義がすべて整った状態でスタートできます。
プロジェクト構造の違い
JavaScript 版と TypeScript 版のプロジェクト構造を比較してみましょう。
JavaScript版(react) TypeScript版(react-ts)
my-react-app/ my-ts-app/
├── src/ ├── src/
│ ├── App.jsx ←→ │ ├── App.tsx # .jsx → .tsx
│ ├── App.css │ ├── App.css
│ ├── main.jsx ←→ │ ├── main.tsx # .jsx → .tsx
│ └── index.css │ ├── index.css
│ │ └── vite-env.d.ts # Vite の型定義(新規)
├── package.json ├── package.json
├── vite.config.js ←→ ├── vite.config.ts # .js → .ts
└── └── tsconfig.json # TypeScript設定(新規)
大きな違いは3つです:
- ファイル拡張子 —
.jsxが.tsxに、.jsが.tsに変わる - tsconfig.json — TypeScript のコンパイル設定ファイルが追加される
- vite-env.d.ts — Vite 固有の型定義ファイルが追加される
.ts と .tsx の使い分け
ファイル拡張子の選び方は明確なルールがあります。
| 拡張子 | 用途 | JSX を含む |
|---|---|---|
.ts | 通常の TypeScript ファイル(ユーティリティ関数、型定義、API呼び出しなど) | 含まない |
.tsx | JSX を含む TypeScript ファイル(React コンポーネント) | 含む |
// utils/formatDate.ts — JSX を使わないので .ts
export function formatDate(date: Date): string {
return date.toLocaleDateString("ja-JP");
}
// components/DateDisplay.tsx — JSX を使うので .tsx
import { formatDate } from "../utils/formatDate";
function DateDisplay({ date }: { date: Date }) {
return <p>今日の日付: {formatDate(date)}</p>;
}
export default DateDisplay;
.ts ファイルの中に JSX(<div> や <Component /> など)を書くとコンパイルエラーになります。JSX を使うファイルは必ず .tsx にしてください。逆に .tsx ファイルで JSX を書かなくてもエラーにはなりませんが、慣習として使い分けましょう。
tsconfig.json を理解する
tsconfig.json は TypeScript のコンパイラ設定ファイルです。Laravel でいう .env ファイルや config/app.php のように、プロジェクト全体の挙動を制御します。
Vite の react-ts テンプレートが生成する設定を見てみましょう。
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* バンドラー向け設定 */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* 型チェックの厳格さ */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
すべてを覚える必要はありません。特に重要な設定だけ押さえておきましょう。
重要な設定項目
| 設定 | 意味 | 推奨値 |
|---|---|---|
target | コンパイル先の JavaScript バージョン | ES2020 |
module | モジュールシステム | ESNext |
jsx | JSX の変換方式 | react-jsx |
strict | 厳格な型チェックを有効にする | true |
noUnusedLocals | 未使用の変数をエラーにする | true |
noUnusedParameters | 未使用の引数をエラーにする | true |
strict: true が有効にする設定
strict: true は複数の厳格チェックを一括で有効にするショートカットです。
{
"strict": true
// 以下がすべて有効になる:
// "noImplicitAny": true — 暗黙の any を禁止
// "strictNullChecks": true — null/undefined の安全なハンドリングを強制
// "strictFunctionTypes": true — 関数型の厳密なチェック
// "strictBindCallApply": true — bind/call/apply の型チェック
// ... その他
}
strict: true は最初から有効にしておくことを強くおすすめします。後から有効にすると大量のエラーが出て修正が大変になるためです。Laravel で declare(strict_types=1) を最初から書くのと同じ発想です。
TypeScript 版の App.tsx を見てみる
生成された App.tsx を見てみましょう。
// src/App.tsx
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() {
// useState に number 型が自動推論される
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
一見すると JavaScript 版とほとんど同じです。しかし TypeScript が裏側で型推論を行っており、count が number であること、setCount が number を受け取る関数であることなどを自動的に把握しています。
開発サーバーで TypeScript のコンパイルを確認する
開発サーバーが起動している状態で、意図的に型エラーを起こしてみましょう。
// src/App.tsx の関数内に追加してみる
function App() {
const count: number = "これは文字列です"; // 型エラー!
// ...
}
VS Code では赤い波線が表示され、ターミナル(Vite のコンソール)にもエラーが表示されます。
Type 'string' is not assignable to type 'number'.
このように、コードを書いた瞬間にエラーが検知されるのが TypeScript の最大の強みです。
Vite の開発サーバーはデフォルトでは型エラーがあってもブラウザにページを表示します。型チェックは VS Code やビルド時(npm run build)に行われます。厳密に型チェックしたい場合は vite-plugin-checker などのプラグインを追加すると、開発サーバーでもエラーをオーバーレイ表示できます。
Laravel / Rails との比較
バックエンド開発者の視点で、TypeScript の設定をおなじみの概念と対比してみましょう。
| TypeScript | Laravel / Rails |
|---|---|
tsconfig.json | .env + config/app.php(プロジェクト設定) |
strict: true | declare(strict_types=1)(PHP)/ Sorbet の typed: strict(Ruby) |
.ts / .tsx ファイル | .php / .blade.php ファイル |
| 型エラー(コンパイル時) | PHPStan / Larastan のエラー |
interface / type | PHP の interface / Laravel の Form Request バリデーション |
npm run build で型チェック | phpstan analyse でコード解析 |
TypeScript の型チェックは PHPStan のレベル設定に似ています。strict: true は PHPStan の最大レベル(レベル9)に相当します。最初から最大レベルで始められるのが、新規プロジェクトの特権です。
vite-env.d.ts について
プロジェクトに含まれる vite-env.d.ts は短いファイルです。
// src/vite-env.d.ts
/// <reference types="vite/client" />
これは Vite が提供する型定義を読み込む宣言です。画像ファイルの import や import.meta.env といった Vite 固有の機能に型を付けてくれます。このファイルは触らずにそのまま残しておきましょう。
以下の手順で Vite + React + TypeScript のプロジェクトを作成してみましょう。
ステップ 1: プロジェクトを作成する
npm create vite@latest my-ts-app -- --template react-ts
cd my-ts-app
npm installステップ 2: 開発サーバーを起動する
npm run devブラウザで http://localhost:5173 を開き、画面が表示されることを確認してください。
ステップ 3: 型エラーを体験する
src/App.tsx を開き、関数の先頭に以下のコードを追加してみましょう。
function App() {
// わざと型を間違えてみる
const message: number = "Hello TypeScript";
console.log(message);
// ...
}VS Code に赤い波線が表示され、エラーメッセージが出ることを確認してください。確認できたら、追加したコードは削除しておきましょう。
ステップ 4: プロジェクト構造を確認する
ファイルエクスプローラーで以下のファイルを開いて中身を確認してみましょう。
tsconfig.json—strict: trueになっていますか?src/App.tsx— 拡張子が.tsxになっていますか?src/vite-env.d.ts—/// <reference types="vite/client" />と書かれていますか?
まとめ
このチャプターでは TypeScript + React の開発環境を構築しました。
- TypeScript は JavaScript に静的型付けを追加した言語で、型安全性・IDE サポート・チーム開発の面で大きなメリットがある
npm create vite@latest -- --template react-tsで TypeScript 対応のプロジェクトが作れる.tsは通常の TypeScript ファイル、.tsxは JSX を含むファイルに使うtsconfig.jsonのstrict: trueは最初から有効にしておくべき- TypeScript のコードはビルド時に JavaScript に変換されるため、ブラウザで直接動く
次のチャプターでは、TypeScript の基本的な型(string、number、boolean など)を学んでいきます。