この記事では、 TypeScript の type と interface の違いを詳しく解説し、それぞれの使用場面について説明します。
TypeScriptを使用する際、開発者は時に type と interface のどちらを使うべきか迷うことがあります。
両者は似たような機能を持っていますが、微妙な違いがあります。
1. type と interface の基本的な定義
まず、 type と interface の基本的な定義方法を見てみましょう。
// typeの定義
type User = {
id: number;
name: string;
email: string;
};
// interfaceの定義
interface User {
id: number;
name: string;
email: string;
}
基本的な使い方では、 type と interface はほぼ同じように見えます。
しかし、以降のポイントで違いが出てきます。
2. type と interface の拡張性
interface の拡張
interface
は extends
キーワードを使って拡張することができます。
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
const myDog: Dog = {
name: "Pochi",
breed: "Tanaka Taro"
};
type の拡張
type
は交差型(Intersection Types)を使って拡張します。
type Animal = {
name: string;
};
type Dog = Animal & {
breed: string;
};
const myDog: Dog = {
name: "Pochi",
breed: "Tanaka Taro"
};
3. type と interface の宣言のマージ
interface
は同じ名前で複数回宣言することができ、それらがマージされます。
interface Car {
brand: string;
}
interface Car {
model: string;
}
const myCar: Car = {
brand: "Toyota",
model: "Corolla"
};
一方、type
は再宣言することができません。
type Car = {
brand: string;
};
// エラー: 重複する識別子 'Car'
type Car = {
model: string;
};
4. type と interface のプリミティブ型の扱い
type
はプリミティブ型に名前を付けることができますが、interface
はオブジェクト型にのみ使用できます。
// OK
type Name = string;
// エラー: プリミティブ型には'interface'を使用できません
interface Age = number;
5. type と interface のユニオン型とインターセクション型
type
はユニオン型とインターセクション型を直接定義できますが、interface
はできません。
type Status = "pending" | "approved" | "rejected";
type NumberOrString = number | string;
type UserWithRole = User & { role: string };
// interface ではこのような定義はできません
(結論) どちらを使うべきか?
-
interface
を使う場合:- オブジェクト型を定義する際
- 拡張性が必要な場合
- 宣言のマージを利用したい場合
- 大規模プロジェクトでのパフォーマンスを重視する場合
-
type
を使う場合:- ユニオン型やインターセクション型を定義する際
- プリミティブ型に別名をつけたい場合
- 複雑な型を表現したい場合
基本的にはinterface
を優先的に使い、interface
で表現できない場合や、より明確に型を表現したい場合にtype
を使うというのが一般的な指針と考えます。
おわりに
TypeScriptのtype
とinterface
は、それぞれに長所があります。
プロジェクトの要件や個人の好みに応じて、適切な方を選択しましょう。
両者の特性を理解し、状況に応じて使い分けることで、より堅牢で保守性の高いコードを書くことができると思います。
コメント