Skip to content

How to Extend Interfaces in TypeScript

摘要:在本教程中,你将学习如何扩展一个接口,允许你将一个接口的属性和方法复制到另一个接口。

扩展一个接口的接口

假设你有一个名为 Mailable 的接口,它包含两个名为 send()queue() 的方法,如下所示。

ts
interface Mailable {
    send(email: string): boolean
    queue(email: string): boolean
}

而你有很多类已经实现了 Mailable 接口。

现在,你想给 Mailable 接口添加一个新的方法,以后像这样发送电子邮件:

ts
later(email: string, after: number): void

然而,向 Mailable 接口添加 later() 方法会破坏当前的代码。

为了避免这种情况,你可以创建一个扩展 Mailable 接口的新接口。

ts
interface FutureMailable extends Mailable {
    later(email: string, after: number): boolean
}

要扩展一个接口,你可以使用 extends 关键字,语法如下:

ts
interface A {
    a(): void
}

interface B extends A {
    b(): void
}

接口 B 扩展了接口 A,这样就有了 a()b() 这两个方法。

和类一样,FutureMailable 接口继承了 Mailable 接口的 send()queue() 方法。

下面展示了如何实现 FutureMailable 接口:

ts
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;
    }
}

扩展多个接口的接口

一个接口可以扩展多个接口,形成所有接口的组合。比如说:

ts
interface C {
    c(): void
}

interface D extends B, C {
    d(): void
}

在这个例子中,接口 D 扩展了接口 BC,所以 D 拥有 BC 接口的所有方法,也就是 a()b()c() 方法。

扩展类的接口

TypeScript 允许一个接口扩展一个类。在这种情况下,接口继承了该类的属性和方法。另外,接口可以继承类的私有和受保护的成员,而不是仅仅继承公共成员。

这意味着,当一个接口扩展了一个具有私有或受保护成员的类时,该接口只能由该类或该接口所扩展的类的子类来实现。

通过这样做,你将接口的使用限制在该接口所扩展的类或该类的子类中。如果你试图从一个不是该接口所继承的类的子类中实现该接口,你会得到一个错误。比如说:

ts
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() { }

}

总结

  • 一个接口可以扩展一个或多个现有的接口。
  • 接口也可以扩展一个类。如果该类包含私有或受保护的成员,则只能由该类或该类的子类实现接口。