In TypeScript, we can’t inherit or extend from more than one class but Mixins helps us to get around that.
在TypeScript中,我们不能从一个以上的类继承或扩展,但是Mixins可以帮助我们解决这个问题。
Mixins create partial classes which we can combine to form a single class that contains all the methods and properties from the partial classes.
混入创建,我们可以结合起来,形成一个包含所有从局部类的方法和属性的单一类部分类。
Say we have two classes, Car
and Lorry
which contain the drive
and carry
methods respectively and we want to create a third class called Truck
. A truck should contain both drive
and carry
methods but we can only extend one class in TypeScript. To solve this, we can use mixins:
假设我们有两个类, Car
和Lorry
,分别包含drive
和carry
方法,我们想创建一个称为Truck
的第三类。 卡车应同时包含drive
方法和carry
方法,但我们只能在TypeScript中扩展一个类。 为了解决这个问题,我们可以使用mixins:
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 {} // error: Classes can only extend a single class
To create a mixin, we’ll take advantage of two functionalities of TypeScript:
要创建一个mixin,我们将利用TypeScript的两个功能:
接口类扩展 (Interface class extension)
Unlike classes, interfaces can extend multiple classes in TypeScript. When an interface extends a class, it extends only the members of the class but not their implementation because interfaces don’t contain implementations.
与类不同,接口可以在TypeScript中扩展多个类。 当接口扩展一个类时,它仅扩展该类的成员,而不扩展其实现,因为接口不包含实现。
interface A extends ClassB,ClassC {}
声明合并 (Declaration merging)
When two or more declarations are declared with the same name, TypeScript merges them into one.
当使用相同的名称声明两个或多个声明时,TypeScript会将它们合并为一个。
interface Alligator {
eyes: number;
nose: number;
}
interface Alligator {
tail: number;
}
// contains properties from both Alligator interfaces
const gator: Alligator = {
eyes: 2,
nose: 1,
tail: 1
};
By leveraging these two functionalities in TypeScript, we can create an interface
with the same name as Truck
and extend both the Car
and Lorry
classes:
通过利用TypeScript中的这两个功能,我们可以创建一个与Truck
同名的interface
,并扩展Car
和Lorry
类:
export class Truck {}
export interface Truck extends Car, Lorry {}
Due to declaration merging, the Truck
class will be merged with the Truck
interface. This means that, the Truck
class will now contain the function definitions from both Car
and Lorry
classes. Remember, just the definitions not the implementation because once again, interfaces don’t contain implementations.
由于声明合并 , Truck
类将与Truck
接口合并。 这意味着Truck
类现在将包含Car
和Lorry
类的函数定义。 记住,只是定义而不是实现,因为接口再一次不包含实现。
To enable the Truck
class to have implementations of the functions inherited from Car
and Lorry
, we’ll use a helper function found in the TypeScript docs.
为了使Truck
类具有从Car
和Lorry
继承的函数的实现,我们将使用TypeScript文档中的helper函数 。
The function takes the name of the class to which we want to copy the implementations to as the first argument, which in our case is Truck
and takes an array of classes from which we want to copy the implementations as the second argument, which in our case is Car
and Lorry
.
该函数将要向其复制实现的类的名称作为第一个参数,在本例中为Truck
,并从一个要从其复制实现的类数组作为第二个参数,在我们的类中案件是Car
和Lorry
。
// the helper function
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
});
});
}
And here’s how it’s used:
以及它的用法:
applyMixins(Truck, [Car, Lorry]);
Now, we can access the methods in Car
and Lorry
from a truck object.
现在,我们可以从卡车对象访问“ Car
和“ Lorry
的方法。
const truck = new Truck();
truck.drive("truck"); // This truck can drive very fast
truck.carry(10); // This vehicle can carry 10 kg
That’s it. Go have some mixin fun. 🎉
而已。 去享受一些mixin的乐趣。 🎉
翻译自: https://www.digitalocean.com/community/tutorials/typescript-mixins