React × TypeScript 入門！初心者でもすぐに使える基本＆ベストプラクティス！

ReactとTypeScriptを組み合わせて開発していると、いろいろな選択肢や考え方が出てきます。
「どの型を使えばいいんだろう？」「書き方のベストプラクティスってあるの？」と悩むこともありますよね。

本記事では、React×TypeScriptの開発でわたしが普段意識しているポイントや、すぐに使えるTipsを紹介します！
TypeScriptの基本もおさらいしながら、実践的なテクニックをサクッと解説していきます。

## 開発のときに意識にしていること

### 🔹 関数の引数には型を指定し、戻り値はTypeScriptに任せる
関数の引数に型をつけることで、意図しない値が渡されるのを防ぐことができます。
ただ、戻り値の型はTypeScriptの型推論を活かしたほうがコードがスッキリすることが多いです。

```typescript
function greet(name: string) {
  return `Hello, ${name}!`;
}
```

戻り値の型を書かなくても、TypeScriptが自動で`string`と判断してくれます。

### ⚖️ 型のつけすぎは避ける

型をたくさんつけることで安全性が高まるのは確かですが、
全部に型をつけすぎると逆に可読性が落ちてしまうことも。
TypeScriptが推論できるところは任せるのがいいバランスだと思います。

```typescript
const age = 30; // TypeScriptがnumber型と認識するのでOK
```

## Reactコンポーネントで意識していること

### 📦 Propsの型定義はシンプルに
ReactコンポーネントのPropsを定義するときは、シンプルなオブジェクト型にするのがわかりやすいです。

```typescript
function UserProfile({ name, age }: { name: string; age: number }) {
  return (
    <div>
      <h1>{name}</h1>
      <p>Age: {age}</p>
    </div>
  );
}
```

「どんなデータを渡せばいいのか」が一目でわかるので、チーム開発でも伝わりやすくなります。

### 🏗 `ReactNode` を使って `children` を型定義する
コンポーネントの `children` には `ReactNode` を指定するのが基本です。

```typescript
import { ReactNode } from 'react';

function Container({ children }: { children: ReactNode }) {
  return <div className="container">{children}</div>;
}
```

`ReactNode` を使えば、文字列・数値・JSXなど幅広い要素を受け取れるので、
汎用性の高いコンポーネントを作るときに便利です。

## 便利な型の活用

### 🔄 `ReturnType` と `Awaited` を使って戻り値の型を取得する
関数の戻り値の型を手動で定義すると、修正時にズレが生じることがあります。
そこで `ReturnType` を使うと、関数の戻り値をそのまま型として取得できます。

```typescript
function getUser() {
  return { name: "Alice", age: 25 };
}

type UserData = ReturnType<typeof getUser>;
```

非同期関数なら `Awaited` も併用すると便利です。

```typescript
async function fetchData() {
  return { name: "Alice", age: 25 };
}

type UserData = Awaited<ReturnType<typeof fetchData>>;
```

こうすることで、関数の戻り値の型定義を一元管理できるので、
修正の際に一箇所だけ変更すれば済みます。

### 🔁 `ComponentProps` を活用して型の再利用を簡単に！

Reactの`ComponentProps`を使うと、既存のコンポーネントのプロパティ型をそのまま再利用できます。
例えば、新しいコンポーネントを作る際に、わざわざ型を再定義しなくても既存の型を活用できるので、コードの重複を防ぎ、可読性とメンテナンス性を向上させることができます。

これにより、例えば入力フォームのカスタムコンポーネントを作成するときに、`input`タグのすべてのプロパティをそのまま引き継ぎつつ、追加のカスタムプロパティを持たせることが可能です。

`ComponentProps` を使うと、既存のHTMLタグやコンポーネントのPropsの型を簡単に再利用できます。

```typescript
import React from 'react';

type CustomInputProps = React.ComponentProps<'input'> & {
  label: string;
};

function CustomInput({ label, ...props }: CustomInputProps) {
  return (
    <label>
      {label}
      <input {...props} className="custom-input" />
    </label>
  );
}

export default function App() {
  return <CustomInput label="Username" placeholder="Enter your username" />;
}
```

### 📌 `as const` でリテラル型を固定する

`as const` を使うと、オブジェクトや配列の値をリテラル型に固定できます。

```typescript
const COLORS = {
  primary: "#ff0000",
  secondary: "#00ff00",
} as const;

type ColorKeys = keyof typeof COLORS;
```

これにより、`COLORS.primary` は `"#ff0000"` のように確定した型を持つようになります。



## まとめ

**React × TypeScript を使うときに意識していること！**

✔ **関数の引数には型をつける！戻り値はTypeScriptにおまかせ！**
✔ **型のつけすぎは避け、シンプルに！**
✔ **Propsの型定義は簡潔にまとめる！**
✔ **`ReactNode` を使って `children` を型定義する！**
✔ **`ReturnType` & `Awaited` で関数の戻り値を型として活用！**
✔ **`ComponentProps` で型を再利用！**
✔ **`as const` でリテラル型を固定！**

これらをうまく活用することで、開発の効率がグッと上がります。
日々の開発で少しずつ試して、自分に合ったスタイルを見つけていきましょう！

それでは、よいエンジニアライフを！ 🚀