複数の型定義をマージする場合は、[[交差型 (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における型エイリアスとインターフェースの違い]]