Como criar decoradores TypeScript personalizados

Decoradores são um recurso no TypeScript que permite modificar classes, métodos, propriedades ou parâmetros em tempo de execução. São funções especiais que fornecem recursos de metaprogramação. No TypeScript, decoradores são frequentemente usados ​​em frameworks como Angular para aprimorar a funcionalidade. Este artigo explica como criar decoradores personalizados passo a passo.

Tipos de decoradores em TypeScript

Existem quatro tipos principais de decoradores no TypeScript:

  • Decoradores de classe
  • Decoradores de Método
  • Decoradores de acessórios
  • Decoradores de imóveis

Habilitando decoradores em TypeScript

Para usar decoradores em um projeto TypeScript, a opção experimentalDecorators deve estar habilitada no arquivo tsconfig.json.

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Criando um decorador de classe

Decoradores de classe são aplicados ao construtor de uma classe. Eles são úteis para adicionar metadados ou funcionalidade à classe. Aqui está um exemplo de como criar um decorador de classe simples.

function logClass(constructor: Function) {
  console.log(`Class ${constructor.name} is created`);
}

@logClass
class Person {
  constructor(public name: string) {}
}

const person = new Person("John");
// Output: Class Person is created

Criando um decorador de método

Os decoradores de método são aplicados a métodos de classe. Eles podem ser usados ​​para modificar ou observar o comportamento do método. Abaixo está um exemplo de um decorador de método que registra a execução do método.

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyKey} is called with arguments:`, args);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a: number, b: number) {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3); 
// Output: Method add is called with arguments: [2, 3]

Criando um decorador de propriedade

Os decoradores de propriedade podem ser usados ​​para observar ou modificar propriedades. Aqui está um exemplo em que um decorador de propriedade garante que uma propriedade tenha um valor padrão.

function defaultValue(value: any) {
  return function (target: any, propertyKey: string) {
    let propertyValue = value;

    const getter = function () {
      return propertyValue;
    };

    const setter = function (newValue: any) {
      propertyValue = newValue || value;
    };

    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true,
    });
  };
}

class User {
  @defaultValue('Anonymous')
  name!: string;
}

const user = new User();
console.log(user.name); // Output: Anonymous
user.name = 'Alice';
console.log(user.name); // Output: Alice

Criando um decorador de parâmetros

Decoradores de parâmetros são aplicados aos parâmetros de um método. Eles podem ser úteis para tarefas como validação ou argumentos de log. Aqui está um exemplo de um decorador de parâmetros.

function logParameter(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} is being decorated`);
}

class Vehicle {
  drive(@logParameter speed: number) {
    console.log(`Driving at speed ${speed}`);
  }
}

const vehicle = new Vehicle();
vehicle.drive(50);
// Output: Parameter at index 0 in method drive is being decorated

Conclusão

Decoradores em TypeScript oferecem poderosos recursos de metaprogramação que podem aprimorar e estender a funcionalidade de classes, métodos e propriedades. Ao usar decoradores personalizados, é possível criar estruturas de código reutilizáveis, eficientes e organizadas. Este guia demonstrou a criação de diferentes tipos de decoradores: classe, método, propriedade e parâmetro.