Mixins - TypeScript
O TypeScript, assim como muitas linguagens orientadas a objetos, como Java ou C#, não permite o uso direto de herança múltipla. Podemos implementar múltiplas interfaces em uma classe, mas só podemos herdar de uma única classe. No entanto, a funcionalidade dos mixins permite, parcialmente, herdar propriedades e métodos de duas ou mais classes simultaneamente.
Vamos considerar um exemplo. Suponha que temos uma classe Animal
Movable
Animal
Movable
class Animal {
feed(): void {
console.log("Feeding the animal");
}
}
class Movable {
speed: number = 0;
move(): void {
console.log("Moving");
}
}
class Horse {}
interface Horse extends Animal, Movable {}
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
applyMixins(Horse, [Animal, Movable]);
let pony: Horse = new Horse();
pony.feed();
pony.move();
Para que a classe Horse
Animal
Movable
Horse
Animal
Movable
interface Horse extends Animal, Movable {}
Mas para que o mixin possa herdar a funcionalidade, isso não é suficiente. Ainda precisamos usar uma função especial que copia a funcionalidade das classes pai para o mixin:
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
Em seguida, aplicamos essa função:
applyMixins(Horse, [Animal, Movable]);
O primeiro parâmetro é a classe mixin, e o segundo parâmetro é um array das classes aplicadas.