Um dos desafios que experimentei com o TypeScript é o limite de apenas herdar ou estender de uma única classe por vez. Você pode contornar essa restrição, especialmente em uma arquitetura mais complexa, usando TypeScript m ixins para melhorar a herança de várias classes.
Neste tutorial, aprenderemos mais sobre mixins em geral, exploraremos mixins TypeScript e examinaremos um caso de uso típico de mixins.
Aqui está o que vamos cobrir:
Para acompanhar este tutorial, você deve ter:
- Um conhecimento básico de TypeScript
- Familiaridade com JavaScript
Usei playcode.io para escrever os programas de exemplo.
O que são mixins?
Mixins são classes especiais que contêm uma combinação de métodos que podem ser usados por outras classes. Mixins promovem a reutilização de código e ajudam a evitar limitações associadas à herança múltipla.
Mesmo que os atributos e parâmetros de instanciação sejam definidos em tempo de compilação, os mixins podem adiar a definição e vinculação de métodos até o tempo de execução.
Criação de mixins com TypeScript
Para criar um mixin, tiraremos vantagem de dois aspectos do TypeScript: extensão de classe de interface e fusão de declaração.
A extensão da classe de interface é usada, sem surpresa, para estender várias classes no TypeScript. A mesclagem de declarações se refere ao processo do TypeScript de mesclar duas ou mais declarações com o mesmo nome. As interfaces também podem ser mescladas em classes e outras construções se tiverem o mesmo nome.
Aqui está um exemplo de fusão de declaração:
interface Car { direção: número; pneu: número; } interface Car { escapeOutlet: número; } //contém propriedades de ambas as interfaces do carro Const BMW: Car={ direção: 1, pneu: 4, escapeOutlet: 2 };
Agora que entendemos esses dois recursos do TypeScript, estamos prontos para começar.
Primeiro, precisamos criar uma classe base na qual os mixins serão aplicados:
classe Bloco { nome=""; comprimento=0; largura=0; altura=0; construtor (nome: string, comprimento: número, largura: número, altura: número,) { this.name=nome; this.length=length; this.breadth=largura; esta.altura=altura; } }
A seguir, crie as classes para as quais a classe base se estenderá:
classe Moulder { moldagem=verdadeiro; feito=falso mofo() { this.moulding=false; this.done=true; } } class Stacker { empilhamento=verdadeiro; feito=falso pilha() { this.stacking=false; this.done=true; } }
Crie uma interface que mescle as classes esperadas com o mesmo nome de sua classe base ( Bloco
):
Bloco de interface
extends Moulder, Stacker {}
A nova interface é definida exatamente com o mesmo nome da classe Bloco
que criamos anteriormente. Isso é crucial porque essa interface está estendendo as classes Moulder
e Stacker
. Isso significa que as interfaces irão mesclar sua definição de método em uma única construção (a interface) enquanto, ao mesmo tempo, serão mescladas na definição de classe com o mesmo nome.
Devido à fusão da declaração, a classe Bloco
será mesclada com a interface Bloco
.
Crie uma função
Para criar uma função para unir duas ou mais declarações de classe, usaremos a função fornecida no TypeScript oficial manual :
function applyMixins (associatedCtor: any, constructors: any []) { constructors.forEach ((baseCtor)=> { Object.getOwnPropertyNames (baseCtor.prototype).forEach ((nome)=> { Object.defineProperty ( DerivadoCtor.protótipo, nome, Object.getOwnPropertyDescriptor (baseCtor.prototype, name) || Object.create (null) ); }); }); }
A função anterior itera nas classes Moulder
e Stacker
e, em seguida, itera em sua lista de propriedades e define essas propriedades na classe Block
. Basicamente, estamos vinculando manualmente todos os métodos e propriedades das classes Moulder
e Stacker
à classe Block
.
Para continuar, execute a função anterior da seguinte maneira e, em seguida, verifique o exemplo abaixo:
applyMixins (Block, [Moldador, Empilhador]);
Exemplo de TypeScript Mixin
deixar cubo=novo Bloco ("cubo", 4, 4, 4); cubo.mould (); cubo.stack (); console.log (cube.length, cube.breadth, cube.height, cube.name, cube.moulding, cube.stacking);
Aqui, atribuímos cubo
à instância da classe base Bloco
. Agora a instância Block
pode acessar diretamente os métodos mold ()
e stack ()
do Moulder
e Classes Stacker
, respectivamente.
Embora existam outras maneiras de criar Mixins do TypeScript, este é o padrão mais otimizado porque depende menos do compilador e mais da sua base de código para garantir que o tempo de execução e o sistema de tipos sejam mantidos em sincronia.
Casos de uso comuns para mixins TypeScript
Vejamos alguns casos de uso de mixins TypeScript que você provavelmente encontrará ou que queira considerar.
Lidando com extensão de várias classes
As classes do TypeScript não podem estender várias classes ao mesmo tempo, a menos que um mixin seja introduzido na interface.
Considere o seguinte snippet:
classe Moulder { moldagem=verdadeiro; feito=falso mofo() { this.moulding=false; this.done=true; } } class Stacker { empilhamento=verdadeiro; feito=falso pilha() { this.stacking=false; this.done=true; } } classe Block extends Moulder, Stacker { construtor () { super() } }
Neste exemplo, a classe Block
tenta estender duas classes ao mesmo tempo sem introduzir o conceito de mixins. Se você adicionar este snippet ao editor online ( playcode.io ), receberá o seguinte erro:
Neste ponto, a única solução para essa limitação é introduzir mixins do TypeScript.
Conclusão
Os mixins do TypeScript são úteis ao construir aplicativos que provavelmente crescerão em complexidade. Ao construir aplicativos TypeScript com arquitetura complexa, você desejará estender várias classes ao mesmo tempo. Com mixins, você pode superar as limitações associadas à herança múltipla.
A postagem Mixins do TypeScript: exemplos e casos de uso apareceu primeiro no LogRocket Blog .