TypeScript でインターフェースを拡張する方法

概要: このチュートリアルでは、あるインターフェースのプロパティとメソッドを別のインターフェースにコピーできる、インターフェースの拡張方法を学習します。

1つのインターフェースを拡張するインターフェース

send()queue() という 2 つのメソッドを含む Mailable と呼ばれるインターフェースがあるとします。

interface Mailable {
    send(email: string): boolean
    queue(email: string): boolean
}Code language: TypeScript (typescript)

そして、Mailable インターフェースを既に実装している多くのクラスがあるとします。

ここで、後でメールを送信する新しいメソッドを Mailable インターフェースに追加したいとします。

later(email: string, after: number): voidCode language: TypeScript (typescript)

しかし、later() メソッドを Mailable インターフェースに追加すると、既存のコードが壊れてしまいます。

これを回避するために、Mailable インターフェースを拡張する新しいインターフェースを作成できます。

interface FutureMailable extends Mailable {
    later(email: string, after: number): boolean
}Code language: TypeScript (typescript)

インターフェースを拡張するには、以下の構文で extends キーワードを使用します。

interface A {
    a(): void
}

interface B extends A {
    b(): void
}
Code language: TypeScript (typescript)

インターフェース B はインターフェース A を拡張し、a()b() の両方のメソッドを持ちます。

クラスと同様に、FutureMailable インターフェースは Mailable インターフェースから send()queue() メソッドを継承します。

FutureMailable インターフェースの実装方法を以下に示します。

class Mail implements FutureMailable {
    later(email: string, after: number): boolean {
        console.log(`Send email to ${email} in ${after} ms.`);
        return true;
    }
    send(email: string): boolean {
        console.log(`Sent email to ${email} after ${after} ms. `);
        return true;
    }
    queue(email: string): boolean {
        console.log(`Queue an email to ${email}.`);
        return true;
    }
}Code language: TypeScript (typescript)

複数のインターフェースを拡張するインターフェース

インターフェースは複数のインターフェースを拡張し、すべてのインターフェースの組み合わせを作成できます。 例えば

interface C {
    c(): void
}

interface D extends B, C {
    d(): void
}
Code language: TypeScript (typescript)

この例では、インターフェース D はインターフェース BC を拡張します。そのため、DBC インターフェースのすべてのメソッド、つまり a()b()c() メソッドを持ちます。

クラスを拡張するインターフェース

TypeScript では、インターフェースがクラスを拡張できます。この場合、インターフェースはクラスのプロパティとメソッドを継承します。また、インターフェースはパブリックメンバーだけでなく、クラスのプライベートメンバーとプロテクトメンバーも継承できます。

これは、インターフェースがプライベートメンバーまたはプロテクトメンバーを持つクラスを拡張する場合、インターフェースは、そのクラスまたはインターフェースが拡張するクラスのサブクラスによってのみ実装できることを意味します。

これにより、インターフェースの使用を、インターフェースが拡張するクラスのクラスまたはサブクラスのみに制限します。インターフェースが継承したクラスのサブクラスではないクラスからインターフェースを実装しようとすると、エラーが発生します。 例えば

class Control {
    private state: boolean;
}

interface StatefulControl extends Control {
    enable(): void
}

class Button extends Control implements StatefulControl {
    enable() { }
}
class TextBox extends Control implements StatefulControl {
    enable() { }
}
class Label extends Control { }


// Error: cannot implement
class Chart implements StatefulControl {
    enable() { }

}Code language: PHP (php)

まとめ

  • インターフェースは、1 つまたは複数の既存のインターフェースを拡張できます。
  • インターフェースはクラスを拡張することもできます。クラスにプライベートメンバーまたはプロテクトメンバーが含まれている場合、インターフェースは、そのクラスまたはそのクラスのサブクラスによってのみ実装できます。
このチュートリアルは役に立ちましたか?