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.
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();
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);
};
}
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.
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.