TypeScriptの型システムを極める:継承と交差でインターフェースを拡張する高度なテクニック
TypeScriptにおけるインターフェースの継承と交差の違い
継承
インターフェースを継承するには、extends
キーワードを使用します。継承されたインターフェースのすべてのプロパティとメソッドは、継承インターフェースにも存在する必要があります。さらに、継承インターフェースは、新しいプロパティやメソッドを追加定義することができます。
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
employeeId: number;
jobTitle: string;
}
上記の例では、Employee
インターフェースはPerson
インターフェースを継承しています。つまり、Employee
オブジェクトは、name
とage
のプロパティに加えて、employeeId
とjobTitle
のプロパティも持つ必要があります。
交差
インターフェースを交差させるには、&
演算子を使用します。交差型は、複数のインターフェースのプロパティとメソッドを組み合わせた新しいインターフェースを作成します。
interface Address {
street: string;
city: string;
state: string;
}
interface Contact {
email: string;
phone: number;
}
interface EmployeeWithContact extends Employee, Address, Contact {}
上記の例では、EmployeeWithContact
インターフェースは、Employee
、Address
、Contact
の3つのインターフェースを交差させています。つまり、EmployeeWithContact
オブジェクトは、name
、age
、employeeId
、jobTitle
、street
、city
、state
、email
、phone
のプロパティを持つ必要があります。
継承と交差の使い分け
継承と交差は、それぞれ異なる目的で使用されます。
- 交差: 複数のインターフェースからプロパティとメソッドを抽出し、新しいインターフェースを作成する場合に使用します。
- 継承: 既存のインターフェースを拡張し、新しい機能を追加する場合に使用します。
一般的に、継承はインターフェース階層を定義する場合に、交差は異なるソースから取得したデータを統合する場合に使用されます。
- 継承は、既存のインターフェースを拡張するために使用します。
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
employeeId: number;
jobTitle: string;
}
function printEmployeeInfo(employee: Employee) {
console.log(`Employee name: ${employee.name}`);
console.log(`Employee age: ${employee.age}`);
console.log(`Employee ID: ${employee.employeeId}`);
console.log(`Employee job title: ${employee.jobTitle}`);
}
const employee: Employee = {
name: "John Doe",
age: 30,
employeeId: 12345,
jobTitle: "Software Engineer"
};
printEmployeeInfo(employee);
このコードでは、Employee
インターフェースはPerson
インターフェースを継承しています。printEmployeeInfo
関数は、Employee
オブジェクトを受け取り、その情報をコンソールに出力します。
interface Address {
street: string;
city: string;
state: string;
}
interface Contact {
email: string;
phone: number;
}
interface EmployeeWithContact extends Employee, Address, Contact {}
function printEmployeeWithContactInfo(employee: EmployeeWithContact) {
console.log(`Employee name: ${employee.name}`);
console.log(`Employee age: ${employee.age}`);
console.log(`Employee ID: ${employee.employeeId}`);
console.log(`Employee job title: ${employee.jobTitle}`);
console.log(`Employee address: ${employee.street}, ${employee.city}, ${employee.state}`);
console.log(`Employee email: ${employee.email}`);
console.log(`Employee phone: ${employee.phone}`);
}
const employee: EmployeeWithContact = {
name: "Jane Doe",
age: 25,
employeeId: 54321,
jobTitle: "Web Developer",
street: "123 Main St",
city: "Anytown",
state: "CA",
email: "[email protected]",
phone: 1234567890
};
printEmployeeWithContactInfo(employee);
型エイリアスを使用して、既存のインターフェースの別名を作成できます。これは、インターフェース名の冗長性を減らすのに役立ちます。
interface Person {
name: string;
age: number;
}
type Employee = Person & {
employeeId: number;
jobTitle: string;
};
上記の例では、Employee
型エイリアスはPerson
インターフェースの別名です。つまり、Employee
変数には、Person
インターフェースと同じプロパティを持つオブジェクトを割り当てることができます。
マージされた型
マージされた型を使用して、2つのインターフェースのプロパティを結合した新しいインターフェースを作成できます。これは、2つのインターフェースに共通のプロパティを持つオブジェクトを表す場合に役立ちます。
interface Person {
name: string;
age: number;
}
interface Contact {
email: string;
phone: number;
}
type PersonWithContact = Person & Contact;
上記の例では、PersonWithContact
型はPerson
とContact
の2つのインターフェースをマージしたものです。つまり、PersonWithContact
変数には、name
、age
、email
、phone
のプロパティを持つオブジェクトを割り当てることができます。
部分的なインターフェース
部分的なインターフェースを使用して、既存のインターフェースのプロパティの一部を定義した新しいインターフェースを作成できます。これは、オプションのプロパティや、特定のコンテキストで使用されるプロパティのみを定義する場合に役立ちます。
interface Person {
name: string;
age: number;
address?: Address;
}
interface Address {
street: string;
city: string;
state: string;
}
上記の例では、PartialPerson
型はPerson
インターフェースの部分的なインターフェースです。つまり、PartialPerson
変数には、name
、age
のプロパティを持つオブジェクトを割り当てることができ、address
プロパティはオプションです。
交差点型
交差型を使用して、複数のインターフェースのプロパティを結合した新しいインターフェースを作成できます。これは、継承と似ていますが、継承とは異なり、新しいプロパティを追加することはできません。
interface Person {
name: string;
age: number;
}
interface Employee {
employeeId: number;
jobTitle: string;
}
type EmployeeWithAge = Person & Employee;
上記の例では、EmployeeWithAge
型はPerson
とEmployee
の2つのインターフェースを交差させたものです。つまり、EmployeeWithAge
変数には、name
、age
、employeeId
、jobTitle
のプロパティを持つオブジェクトを割り当てることができます。
TypeScriptインターフェースを拡張するには、継承と交差以外にもいくつかの方法があります。それぞれの方法には長所と短所があり、状況に応じて適切な方法を選択する必要があります。
- 交差型: 複数のインターフェースのプロパティを結合する
- 部分的なインターフェース: 既存のインターフェースのプロパティの一部を定義する
- 型エイリアス: インターフェース名の冗長性を減らす
typescript types intersection