介绍
在 TypeScript 中,我们不能从多个类继承或扩展,但是 Mixins 可以帮助我们解决这个问题。
Mixins 创建部分类,我们可以将它们组合成一个类,其中包含部分类的所有方法和属性。
注意: 文档将本教程中的方法描述为“替代模式”。
在本教程中,您将在 TypeScript 中创建和使用 mixin。
了解类的局限性
让我们创建一个示例,以便我们可以展示 mixins 的价值。
考虑两个类,Car 和 Lorry,它们分别包含 drive 和 carry 方法。 然后,考虑称为 Truck 的第三类。 Truck 应该包括 drive 和 carry 方法:
应用程序.ts
export class Car {
drive(name:string) {
console.log(`This ${name} can drive very fast`);
}
}
export class Lorry {
carry(weight:number) {
console.log(`This vehicle can carry ${weight} kg`);
}
}
export class Truck extends Car, Lorry {}
这是行不通的,因为我们只能扩展一个类。
Outputerror: Classes can only extend a single class
为了解决这个问题,我们可以使用 mixins。
了解接口类扩展和声明合并
为了创建一个 mixin,我们将利用 TypeScript 的两个功能:
接口类扩展
与类不同, 接口可以在 TypeScript 中扩展多个类。
应用程序.ts
interface A extends ClassB, ClassC {}
当接口扩展一个类时,它只扩展类成员而不扩展它们的实现,因为接口不包含实现。
声明合并
当使用相同名称声明两个或多个声明时,TypeScript 会将它们合并为一个 。
应用程序.ts
interface Alligator {
eyes: number;
nose: number;
}
interface Alligator {
tail: number;
}
const gator: Alligator = {
eyes: 2,
nose: 1,
tail: 1
};
gator 包含来自两个 Alligator 接口的属性。
使用辅助函数
通过利用 TypeScript 中的这两个功能,我们可以创建一个与 Truck 同名的接口,并扩展 Car 和 Lorry 类:
应用程序.ts
export class Truck {}
export interface Truck extends Car, Lorry {}
由于声明合并,Truck类将与Truck接口合并。 这意味着 Truck 类现在将包含来自 Car 和 Lorry 类的函数定义。
为了使 Truck 类能够实现从 Car 和 Lorry 继承的函数,我们将使用 TypeScript 文档 中的 辅助函数。
该函数将我们想要复制实现的类的名称作为第一个参数(在我们的例子中是 Truck),并将我们想要从中复制实现的类的数组作为第二个参数参数(在我们的例子中是 Car 和 Lorry)。
应用程序.ts
// the helper function
function applyMixins(derivedCtor: any, constructors: any[]) {
constructors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
Object.create(null)
);
});
});
}
以下是它的使用方法:
应用程序.ts
applyMixins(Truck, [Car, Lorry]);
我们现在可以从 truck 对象访问 Car 和 Lorry 中的方法。
应用程序.ts
const truck = new Truck();
truck.drive("truck");
truck.carry(10);
此代码将产生以下输出:
OutputThis truck can drive very fast This vehicle can carry 10 kg
这个truck可以访问drive()和carry()。
结论
在本教程中,您在 TypeScript 中创建并使用了 mixin。
从这里,学习 如何使用 TypeScript 声明合并接口。