複数の型定義をマージする場合は、[[交差型 (TypeScript)|交差型]]より[[インターフェース (TypeScript)|インターフェース]]を使ったほうがよい。
> For this reason, extending types with `interface`s/`extends` is suggested over creating intersection types.
>
> *[Performance](https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections) *
理由は以下のとおり。
## プロパティの衝突を検知できる
[[交差型はプロパティの衝突を検知できない (TypeScript)|交差型はプロパティの衝突を検知できない]]が、[[インターフェースはプロパティの衝突を検知できる (TypeScript)|インターフェースはプロパティの衝突を検知できる]]。
わざと衝突させて型をマージさせるケースは多くないので、早期に型エラーとして検出される方が望ましい。
## 型の関連がわかりやすい
> [!thinking] 本当にメリットなのだろうか?
[[インターフェース (TypeScript)|インターフェース]]は一貫して定義を展開しない。
```ts
type A = {a: string}
type B = {b: string}
type C = {c: string}
type D = {d: string}
interface AB extends A, B {}
interface CD extends C, D {}
interface ABCD extends AB, CD {}
// ^? ABCD
```
[[交差型 (TypeScript)|交差型]]はネスト定義した場合に途中の過程が省略される。
```ts
type A = {a: string}
type B = {b: string}
type C = {c: string}
type D = {d: string}
type AB = A & B;
type CD = C & D;
type ABCD = AB & CD;
// ^? ABCD: A & B & C & D
// コードを確認しなければ AB & CD であることがわからない
```
ただ、**ホバーDocで型の最終系を確認したい** 場合は必ずしもデメリットとは言えないし、[[インターフェース (TypeScript)|インターフェース]]の関連を知りたければソースコードを追跡する必要があり、それは[[型エイリアス (TypeScript)|型エイリアス]]でも可能である。
## 型の関連がキャッシュされる
[[インターフェース (TypeScript)|インターフェース]]は途中の型関連の計算結果がキャッシュされるので、パフォーマンスの優位性がある。
```ts
type A = { a: string };
type B = { b: string };
// AB1がキャッシュされる / A & B は計算
interface AB1 extends A, B {}
// AB2がキャッシュされる / A & B はAB1定義時のキャッシュを利用
interface AB2 extends A, B {}
```
[[型エイリアス (TypeScript)|型エイリアス]]は途中の型関連の計算結果がキャッシュされない。
```ts
type A = { a: string };
type B = { b: string };
// AB1がキャッシュされる / A & B は計算
type AB1 = A & B;
// AB2がキャッシュされる / A & B は計算
type AB2 = A & B;
```
> [!thinking]
> [[型エイリアス (TypeScript)|型エイリアス]]を使う場合でも、名前をつけて中間結果を定義していれば変わらないはず。[[交差型 (TypeScript)|交差型]]を定義する場合はこのケースが多いと思うのであまり変わらない気も?
>
> ```ts
> type A = { a: string };
> type B = { b: string };
>
> // ABがキャッシュされる / A & B は計算
> type AB = A & B;
> // AB1がキャッシュされる / ABはキャッシュを利用
> type AB1 = AB;
> // AB2がキャッシュされる / ABはキャッシュを利用
> type AB2 = AB;
> ```
## すべての構成要素を確認する必要がない
[[インターフェース (TypeScript)|インターフェース]]は最終的な型定義に対してのみ確認するため、パフォーマンスの優位性がある。[[型エイリアス (TypeScript)|型エイリアス]]の[[交差型 (TypeScript)|交差型]]は個別の構成要素に対しても確認が必要になる。
## 参考
- [[📰TypeScriptにおける型エイリアスとインターフェースの違い]]