Decorators em TypeScript: O Que São e Como Utilizá-los

18/09/2024

O Que São Decorators no TypeScript?

Decorators no TypeScript são uma funcionalidade que permite adicionar metadados e modificar o comportamento de classes, métodos, propriedades ou parâmetros. Eles são amplamente utilizados em frameworks como Angular para modificar a estrutura e comportamento do código de maneira declarativa.

Decorators são funções especiais que podem ser aplicadas a classes ou elementos dentro de classes. Quando um decorator é aplicado, ele pode alterar o comportamento padrão de uma função ou adicionar informações extras ao código.

Tipos de Decorators no TypeScript

Existem diferentes tipos de decorators no TypeScript, cada um aplicável a diferentes partes do código. Os principais tipos são:

  • Class Decorator: Aplicado diretamente a uma classe para modificar ou adicionar comportamento.
  • Method Decorator: Utilizado em métodos de uma classe para alterar seu comportamento.
  • Property Decorator: Aplicado a propriedades dentro de uma classe.
  • Parameter Decorator: Utilizado para decorar parâmetros de métodos.

Como Utilizar Decorators

Decorators são definidos como funções que recebem como argumento o elemento que está sendo decorado. Abaixo estão exemplos de como usar cada tipo de decorator.

Class Decorator

Um class decorator é aplicado diretamente sobre a definição da classe e pode modificar ou estender a funcionalidade da classe.

function LogarClasse(constructor: Function) {
    console.log('Classe criada:', constructor.name);
}

@LogarClasse
class Pessoa {
    constructor(public nome: string) {}
}

const pessoa = new Pessoa('Mauro');
// Saída: Classe criada: Pessoa

No exemplo acima, o decorator @LogarClasse adiciona um comportamento para logar o nome da classe toda vez que uma nova instância dela é criada.

Method Decorator

Um method decorator é usado para modificar o comportamento de métodos de uma classe.

function LogarMetodo(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const metodoOriginal = descriptor.value;
    descriptor.value = function (...args: any[]) {
        console.log(`Chamando ${propertyKey} com argumentos:`, args);
        return metodoOriginal.apply(this, args);
    };
}

class Calculadora {
    @LogarMetodo
    somar(a: number, b: number) {
        return a + b;
    }
}

const calc = new Calculadora();
calc.somar(2, 3);
// Saída: Chamando somar com argumentos: [2, 3]

Esse decorator @LogarMetodo adiciona um comportamento para logar os argumentos passados ao método somar sempre que ele for chamado.

Property Decorator

Decorators de propriedades são utilizados para alterar ou monitorar o comportamento de uma propriedade de classe.

function LogarPropriedade(target: any, propertyKey: string) {
    console.log(`Propriedade definida: ${propertyKey}`);
}

class Produto {
    @LogarPropriedade
    preco: number;

    constructor(preco: number) {
        this.preco = preco;
    }
}

const produto = new Produto(100);
// Saída: Propriedade definida: preco

Neste exemplo, o decorator @LogarPropriedade loga o nome da propriedade preco sempre que ela é definida.

Parameter Decorator

Decorators de parâmetros são aplicados a parâmetros de métodos dentro de uma classe, permitindo adicionar metadados ao argumento.

function LogarParametro(target: any, propertyKey: string, parameterIndex: number) {
    console.log(`Parâmetro decorado no método: ${propertyKey}, posição: ${parameterIndex}`);
}

class Servico {
    imprimir(@LogarParametro texto: string) {
        console.log(texto);
    }
}

const servico = new Servico();
servico.imprimir('Olá, mundo!');
// Saída: Parâmetro decorado no método: imprimir, posição: 0

O decorator @LogarParametro loga informações sobre o parâmetro decorado, incluindo o nome do método e a posição do parâmetro.

Boas Práticas ao Utilizar Decorators

  • Use Decorators Com Moderação: Embora os decorators sejam poderosos, usá-los em excesso pode dificultar a manutenção do código. Use-os apenas quando necessário.
  • Mantenha Funções Simples: Decorators devem ser funções simples e previsíveis, que não introduzam comportamentos inesperados ou difíceis de depurar.
  • Documente Seus Decorators: Como os decorators alteram o comportamento do código, é importante documentar claramente o que eles fazem para facilitar o entendimento de outros desenvolvedores.

Conclusão

Decorators são uma funcionalidade avançada do TypeScript que permite adicionar metadados e modificar o comportamento de classes e seus elementos de forma declarativa. Eles são amplamente usados em frameworks como Angular, mas podem ser úteis em diversos cenários, especialmente para adicionar funcionalidades de forma limpa e organizada. No entanto, é importante usar decorators com moderação e seguir boas práticas para manter o código legível e fácil de manter.