【Next.js/React】結局PropsではTypeとInterfaceどっちを使えばいいの？(TypeScriptにおけるTypeとInterfaceの違いとは？)

## 結論
ずばり結論からいうと
**どちらでもいいからプロジェクトを始めるときにどちらを使うのか決めること**
結局はどちらにも向いていること、向いていないことがあるため、それぞれを理解し、場合によって使い分ける必要があります。本記事ではその理解ができればいいと思っています。

## はじめに
ReactでTypeScriptを組み合わせて開発を行う際、コンポーネントのPropsを定義する方法として`type`と`interface`の2つがあります。どちらを使うべきか迷ったことはありませんか？また、それぞれの違いやメリット・デメリットについて深く理解しているでしょうか。

本記事では、`type`と`interface`の違いや長所と短所を詳しく解説し、最終的にどちらを使うべきかについて考察します。

:::note info
一応Next.jsの公式のドキュメントでは`interface`を推奨しているようですが、`Use interface till you need type`と言われているくらい、とりあえずは`interface`でいいよという弱い推奨のようです
:::

https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/basic_type_example#tldr

https://x.com/orta/status/1356129195835973632

## `type`と`interface`の違い

まずは、TypeScriptでの`type`と`interface`の基本的な違いを理解しましょう。

### `type`（型エイリアス）

`type`は型エイリアスを定義するために使用します。これにより、より複雑な型をシンプルな名前で表現できます。

```typescript
type User = {
  name: string;
  age: number;
};
```

### `interface`

`interface`はオブジェクトの構造（形状）を定義するために使用します。プロパティやメソッドの型を指定できます。

```typescript
interface User {
  name: string;
  age: number;
}
```

## メリットとデメリット

### `type`のメリット

1. **柔軟性が高い**

   - ユニオン型やタプル型など、複雑な型の定義が可能です。

   ```typescript
   type Status = 'success' | 'error' | 'loading';
   ```

2. **プリミティブ型やジェネリック型の定義**

   - 型のエイリアスとして使用でき、コードの可読性を高めます。

   ```typescript
   type ID = string | number;
   ```

3. **コンポジションが容易**

   - 型の合成が簡単で、複数の型を組み合わせて新しい型を作成できます。

   ```typescript
   type Person = {
     name: string;
   };
   type Employee = Person & {
     employeeId: number;
   };
   ```

### `type`のデメリット

1. **宣言のマージができない**

   - 同じ名前で複数の`type`を宣言するとエラーになります。

   ```typescript
   type User = {
     name: string;
   };

   // エラー: 既に存在する型名を再宣言できない
   type User = {
     age: number;
   };
   ```

2. **拡張性がやや低い**

   - 型の拡張が`interface`に比べて直感的でない場合があります。

### `interface`のメリット

1. **宣言のマージが可能**

   - 同じ名前の`interface`を複数回宣言すると、自動的にマージされます。

   ```typescript
   interface User {
     name: string;
   }

   interface User {
     age: number;
   }

   // Userは{name: string; age: number;}として扱われる
   ```

2. **クラスの実装を強制できる**

   - クラスに対して`implements`を使用し、特定のプロパティやメソッドの実装を要求できます。

   ```typescript
   interface Serializable {
     serialize(): string;
   }

   class User implements Serializable {
     serialize() {
       return JSON.stringify(this);
     }
   }
   ```

3. **拡張が容易**

   - `extends`を使用して既存の`interface`を拡張できます。

   ```typescript
   interface Person {
     name: string;
   }

   interface Employee extends Person {
     employeeId: number;
   }
   ```

### `interface`のデメリット

1. **柔軟性が低い**

   - プリミティブ型のエイリアスやユニオン型、タプル型の定義が直接できません。

   ```typescript
   // エラー: 'interface'でユニオン型を定義できない
   interface Status = 'success' | 'error' | 'loading';
   ```

2. **型の合成がやや複雑**

   - 複数の`interface`を組み合わせる場合、`&`を使用する必要があります。


## ReactのProps定義での使い分け

### `type`でのProps定義

```typescript
type ButtonProps = {
  label: string;
  onClick: () => void;
};

const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
  <button onClick={onClick}>{label}</button>
);
```

### `interface`でのProps定義

```typescript
interface ButtonProps {
  label: string;
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
  <button onClick={onClick}>{label}</button>
);
```

### どちらを使うべきか？

#### 結論

私は**Propsの定義には`type`を使うことを推奨**します。

#### 理由

- **柔軟性が高い**: ユニオン型やタプル型など、複雑な型を定義しやすいため。
- **堅牢性**: 同じ名前のtypeは存在することがなく、

また、拡張することがあまりないため、ライブラリ開発などで型を拡張する必要がある場合などの例外を除いては、`type`の方がいいと感じた。

しかし、結局一番大切なのは

<font color="red">**`type`か`interface`どちらを使うかプロジェクトごとに一貫性を持つこと** </font>


## まとめ

- **Propsの定義には`type`を使用するのがおすすめ**
  - 柔軟性が高く、複雑な型の表現に適しているため。
- **`interface`はクラスの実装やライブラリ開発で使用する**
  - 宣言のマージや拡張が必要な場合に有用。
- **一貫性を持つことが重要**
  - チームやプロジェクト内で`type`と`interface`の使い分け方針を統一すると、可読性とメンテナンス性が向上します。

## おわりに

今回は、私がプロジェクトに関わる中で抱いたPropsでは`type`と`interface`は使うのがいいのか？何が違うのか調べた結果を書きました。これについてはかなり意見がわかれる論争となる題材だと思っています。**ご意見やご質問がありましたら、ぜひコメントでお知らせください！**それではみなさん，いいエンジニアライフを〜👋

## 参考資料

- [TypeScript公式ドキュメント - TypeScript Deep Dive](https://www.typescriptlang.org/docs/handbook/2/objects.html)