この記事では、 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は、それぞれに長所があります。
プロジェクトの要件や個人の好みに応じて、適切な方を選択しましょう。
両者の特性を理解し、状況に応じて使い分けることで、より堅牢で保守性の高いコードを書くことができると思います。


コメント