TypeScriptでは、interfaceとtypeはどちらもオブジェクトや関数の構造を定義するために使用されますが、微妙な違いや使用上の特徴があります。それぞれの違いについて詳しく説明します。
1. 基本的な用途
-
interface: オブジェクトの構造を定義するためのキーワードです。オブジェクトのプロパティ、メソッド、関数の型を定義できます。特に、クラスやオブジェクトの構造を他のコードと共有する場合によく使われます。 -
type: より汎用的な型エイリアスを作成するためのキーワードです。オブジェクトの構造だけでなく、プリミティブ型、ユニオン型、タプル型など、さまざまな型を定義できます。
2. 拡張とマージ
-
interfaceの拡張:-
interfaceは、他のインターフェースをextendsして拡張できます。また、同じ名前のinterfaceが複数回宣言された場合、自動的にマージされます。 -
例:
interface Person { name: string; } interface Employee extends Person { employeeId: number; } // マージ例 interface Person { age: number; } // 結果: { name: string; age: number; }
-
-
typeの拡張:-
typeは&(交差型)を使用して拡張できますが、同じ名前のtypeを再定義してマージすることはできません。 -
例:
type Person = { name: string; }; type Employee = Person & { employeeId: number; };
-
3. 柔軟性と制約
-
interfaceの制約:-
interfaceはクラスで実装するためのインターフェースとしても使われ、特にオブジェクトの構造に対して明確に適しており、オブジェクト指向プログラミングでの利用が推奨されます。
-
-
typeの柔軟性:-
typeはユニオン型やタプル型、その他の複雑な型を作成するのに適しています。たとえば、string | numberのようなユニオン型や、特定のリテラル型を定義できます。 -
例:
type ID = string | number; type Tuple = [string, number];
-
4. 使用例
-
interface:interface User { id: number; name: string; greet(): void; } const user: User = { id: 1, name: 'Alice', greet() { console.log('Hello'); }, }; -
type:type User = { id: number; name: string; greet: () => void; }; const user: User = { id: 1, name: 'Alice', greet() { console.log('Hello'); }, };
5. 結論と推奨事項
-
interfaceを選ぶ理由: オブジェクトの構造を定義する必要があり、拡張や自動マージが必要な場合に適しています。また、クラスの実装にも使われるため、オブジェクト指向プログラミングでの使用に向いています。 -
typeを選ぶ理由: プリミティブ型、ユニオン型、タプル型、または複雑な型のエイリアスを定義したい場合に適しています。typeは柔軟性が高いため、より多用途に使えることが特徴です。
一般的に、プロジェクトのニーズに合わせてinterfaceとtypeを使い分けるのが良いです。interfaceはオブジェクト構造に特化し、typeは型のエイリアス全般に対応するものとして考えると理解しやすいでしょう。