Seleccionar página

En este consejo quiero compartir cómo ajustar los métodos de clase mediante decoradores, para crear, por ejemplo, un registro donde se puede ver cuando se ejecuta un método.

Los decoradores están en la propuesta ecmaScripts pero creo que será más fácil hacer el ejercicio con CodeSandbox y TypeScript.

Preparación del ejercicio

Primero necesitamos crear un nuevo CodeSandbox usando la plantilla TypeScript.

Image for post

Ejemplo de creación de un entorno limitado para TS

Ahora es el momento de modificar tsconfig.json el archivo y agregar soporte experimental para los decoradores.

"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6"

Podemos crear una Example clase que será útil para probar nuestro decorador.

class Example {
  public myMethod(): void {
    console.log("This is a method");
  }
}const example = new Example();
example.myMethod();

Image for post

Clase de ejemplo

Creación de nuestro decorador de propiedades

Ahora, simplemente cree una función llamada log que devuelva a e implemente la PropertyDecorator función return con tres parámetros:

  • objetivo: el constructor o prototipo de la clase decorada.
  • propertyKey: el nombre de la clave.
  • descriptor(ES6): el descriptor de esa propiedad.

Crea la función y decora tu método usando@log()

function log() {
  return function(target: unknown, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log(target, propertyKey, descriptor);
  };
}

Image for post

Ejemplo de decoración

Envolviendo el método con ES6

Si está trabajando con ES6 (eso significa que descriptor no está indefinido) para ajustar el método será fácil como crear una función alrededor de él.

function log() {
  return function(target: unknown, propertyKey: string, descriptor: PropertyDescriptor) {
    const value = descriptor.value;
    descriptor.value = function(...args: any[]) {
      value.apply(this, args);
      console.log(`${propertyKey} was executed.`);
    };
  };
}

Esto va a registrar el nombre de la propiedad cada vez que se ejecuta.

Image for post

Si no estás listo para ES6

Si descriptor es indefinido, es porque el proyecto aún no está listo para ES6 en ese caso puede redefinir la propiedad.

function log() {
  return function(target: any, propertyKey: string) {
    const value = target[propertyKey];
    const descriptor = {
      value: function(...args: any[]) {
        value.apply(this, args);
        console.log(`${propertyKey} was executed.`);
      }
    };    Reflect.deleteProperty(target, propertyKey);
    Reflect.defineProperty(target, propertyKey, descriptor);
  };
}

Si es necesario, también puede agregar metadatos reflejados a sus dependencias.
Compruebe la demostración en mi CodeSandbox

Si quieres, puedes leer este post en inglés en mi blog de Medium.

0