Skip to content

Instantly share code, notes, and snippets.

@Gustavo-Kuze
Last active May 13, 2022 21:26
Show Gist options
  • Save Gustavo-Kuze/486ab383494683e5e6efa8d8ffc93473 to your computer and use it in GitHub Desktop.
Save Gustavo-Kuze/486ab383494683e5e6efa8d8ffc93473 to your computer and use it in GitHub Desktop.
Como criar TypeScript decorators

O que são decorators?

No TypeScript é possível criarmos funções que alteram o comportamento de outras funções (ou classes), sem que tenhamos que alterar a implementação original da mesma. Essas funções são chamadas decorators

Um decorator pode ser declarado da seguinte maneira:

export default function decoratorFunction(logInSeconds: boolean = false) {
  return function (
    target: any, // contexto onde o decorator está inserido
    propertyKey: string, // Nome do método
    descriptor: PropertyDescriptor // description.value é o método original
  ) {
    const originalFunction = descriptor.value;

    // aqui podemos sobrescrever o comportamento do método original
    descriptor.value = function (...args: any[]) {
      const result = originalFunction.apply(this, args);

    /*
        aqui devolvemos o mesmo retorno do método original
        à partir da chamada do decorator
    */
      return result;
    };

    return descriptor; // é necessário retornar o próprio descriptor ao final
  };
}

Exemplo de decorator real

export default function logProcessingTime(logInSeconds: boolean = false) {
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    const originalFunction = descriptor.value;

    descriptor.value = function (...args: any[]) {
      let divisor = logInSeconds ? 1000 : 1;
      let unidade = logInSeconds ? "seconds" : "milliseconds";

      console.log("-----------------------");
      console.log(`${propertyKey} function params: ${JSON.stringify(args)}`);

      const initialTime = performance.now();

      const result = originalFunction.apply(this, args);
      console.log(`${JSON.stringify(result)} function result:`);

      const finalTime = performance.now();

      console.log(
        `${propertyKey} took ${(finalTime - initialTime) / divisor} ${unidade} to be processed`
      );
      console.log("-----------------------");

      return result;
    };
    return descriptor;
  };
}

Como utilizar o decorator logProcessingTime

Agora basta importar o decorator em qualquer módulo do node que quisermos, e decorar nossa função com ele. Isso fará com que o tempo de execução da função seja mostrado no console do navegador.

Ex:

import logProcessingTime from './decorators/logProcessingTime';

@logProcessingTime()
async function listarUsuariosAsync() {
    // Exemplo de chamada muito demorada à nossa API Rest
    return API.get('/users');
}

// ........

const users = await listarUsuariosAsync(); // adiciona took 1.580000011017546ms to be processed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment