TypeScriptには、オブジェクトや関数の構造を明確に定義するためのインターフェース(interface)と型エイリアス(type alias)という2つの機能があります。これらを活用することで、コードの可読性や再利用性を向上させ、大規模なプロジェクトでも効率的に開発を進めることができます。本記事では、インターフェースと型エイリアスの違いや、それぞれの活用方法について解説します。
[目次を開く]
1. インターフェース(interface)
インターフェースは、オブジェクトの構造や型を定義するためのツールです。インターフェースを使うことで、オブジェクトがどのようなプロパティやメソッドを持つかを型レベルで指定でき、静的に型チェックを行えます。
インターフェースの基本
以下は、インターフェースの基本的な使用例です。
interface User {
name: string;
age: number;
isActive: boolean;
}
const user: User = {
name: "Alice",
age: 30,
isActive: true
}; この例では、Userインターフェースを定義し、そのインターフェースに基づいてuserオブジェクトが作成されています。Userインターフェースでは、nameはstring、ageはnumber、そしてisActiveはbooleanである必要があります。これにより、間違った型の値が指定された場合、TypeScriptがエラーを発生させます。
インターフェースの拡張(継承)
インターフェースは他のインターフェースを継承して拡張することができます。これにより、共通のプロパティを持つインターフェースを再利用しながら、新しいプロパティを追加することが可能です。
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
salary: number;
}
const employee: Employee = {
name: "John",
age: 25,
salary: 50000
}; この例では、PersonインターフェースをEmployeeインターフェースが継承し、新たにsalaryプロパティを追加しています。Employee型のオブジェクトは、name, age, salaryの3つのプロパティを持つことが要求されます。
オプショナルプロパティ
インターフェース内で、必須ではないプロパティを定義したい場合、プロパティ名の後に?を付けることでオプショナルなプロパティにできます。
interface Car {
brand: string;
model: string;
year?: number; // オプショナルプロパティ
}
const myCar: Car = {
brand: "Toyota",
model: "Corolla"
}; この例では、yearプロパティはオプショナルとなっているため、指定しなくてもエラーにはなりません。
インターフェースでメソッドを定義
インターフェースは、オブジェクトのプロパティだけでなく、メソッドの型も定義できます。メソッドは、関数の引数や戻り値の型も指定可能です。
interface Calculator {
add(a: number, b: number): number;
subtract(a: number, b: number): number;
}
const calculator: Calculator = {
add: (x, y) => x + y,
subtract: (x, y) => x - y
}; この例では、Calculatorインターフェースに2つのメソッドaddとsubtractが定義されています。それぞれのメソッドは、引数としてnumber型の値を受け取り、戻り値もnumber型であることが保証されています。
2. 型エイリアス(type alias)
型エイリアスは、typeキーワードを使用して、型に別名を付けることができる機能です。型エイリアスはインターフェースと似ていますが、より柔軟に型を定義できるという利点があります。
基本的な型エイリアス
型エイリアスは、複雑な型をシンプルに表現するために使われます。オブジェクトの型定義やユニオン型の定義にも活用できます。
type User = {
name: string;
age: number;
};
const user: User = {
name: "Alice",
age: 25
}; この例では、User型エイリアスを作成し、それを使ってuserオブジェクトを定義しています。型エイリアスを使うことで、複雑な型を何度も定義する手間が省けます。
型エイリアスとユニオン型
型エイリアスの強力な機能の一つが、ユニオン型を定義できる点です。ユニオン型は、複数の型を組み合わせて、どちらか一方の型であれば良い、という柔軟な型指定ができます。
type ID = string | number;
let userId: ID;
userId = 123; // OK
userId = "abc"; // OK この例では、IDという型エイリアスを作成し、stringまたはnumberのいずれかが許容される型を定義しています。ユニオン型を使うことで、より柔軟な型定義が可能になります。
型エイリアスとインターフェースの違い
型エイリアスとインターフェースは似た目的で使われますが、次のような違いがあります。
- インターフェースは拡張が可能
インターフェースは継承によって他のインターフェースを拡張できます。一方で、型エイリアスは
extendsのような継承機能はありませんが、ユニオン型や交差型を用いた柔軟な型定義ができます。 - 型エイリアスは型の結合に強い
型エイリアスは、ユニオン型やタプル、関数型など、さまざまな型を表現するのに適しています。インターフェースはオブジェクト構造に特化していますが、型エイリアスは任意の型に名前を付けることができ、表現力が高いです。
交差型を使った型の結合
型エイリアスでは、交差型(Intersection Types)を使用して、複数の型を結合することも可能です。
type Name = {
name: string;
};
type Age = {
age: number;
};
type Person = Name & Age;
const person: Person = {
name: "Alice",
age: 30
}; この例では、Name型とAge型を&で結合し、Person型を定義しています。このように交差型を使うと、複数の型の特性を持つオブジェクトを簡単に定義できます。
まとめ
TypeScriptのインターフェースと型エイリアスは、どちらも型安全性を確保し、コードの構造を明確にするための強力なツールです。インターフェースはオブジェクト構造に特化し、継承による拡張が得意ですが、型エイリアスは柔軟にユニオン型や交差型などを定義できる点で優れています。プロジェクトのニーズに応じて、インターフェースと型エイリアスを使い分けることで、より効率的で保守性の高いコードを作成することができます。

