Decoradores
Son una función normal
1. Implementar en tsconfig.json
En Nest lo hace automáticamente.
tsconfig.json
{
"compilerOptions": {
// -----------------------------------------------------------------------------
"experimentalDecorators": true,
// -----------------------------------------------------------------------------
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
/* Linting */
},
"include": ["src"]
}
2. Definir decorator
Al usarse obtiene la referencia al target.
El target es la definición de la clase donde se usa el decorador; propiedades, constructor, métodos, etc.
Puede expandir, extender, añadir funcionalidades, bloquear funcionalidades, remover funcionalidades, sobreescribir la clase, etc.
const MiDecorador = () => {
return (target: Function) => {
//console.log(target);
// puede retornar otra clase para soreescribir la principal
return NewPokemon;
};
};
// otra clase
class NewPokemon {
constructor(public readonly id: number, public name: string) {}
scream() {
console.log(`${this.name.toUpperCase()}!!!`);
}
speak() {
console.log(`${this.name}, ${this.name}!`);
}
}
3. Implementar decorador
// 2. Usar decorador
@MiDecorador()
export class Pokemon {
constructor(public readonly id: number, public name: string) {}
scream() {
console.log(`${this.name.toUpperCase()}!!!`);
}
speak() {
console.log(`${this.name}, ${this.name}!`);
}
}
export const charmander = new Pokemon(4, "Charmander");
Otro ejemplo
deprecated.decorator.ts
const Deprecated = (deprecationReason: string) => {
return (
target: any,
memberName: string,
propertyDescriptor: PropertyDescriptor
) => {
// console.log({target})
return {
get() {
const wrapperFn = (...args: any[]) => {
console.warn(
`Method ${memberName} is deprecated with reason: ${deprecationReason}`
);
//! Llamar la función propiamente con sus argumentos
propertyDescriptor.value.apply(this, args);
};
return wrapperFn;
},
};
};
};
export class Pokemon {
constructor(public readonly id: number, public name: string) {}
scream() {
console.log(`${this.name.toUpperCase()}!!!`);
}
// usar decorador ----------------------------------------------------------------
@Deprecated("Utilizar la version2 del metodo")
speak() {
console.log(`${this.name}, ${this.name}!`);
}
speak2() {
console.log(`${this.name}, ${this.name}!`);
}
}
// crear instancia y ver funcionamiento del decorador ------------------------------
export const charmander = new Pokemon(4, "Charmander");
// Al utilizar speack() se mostrará el mensaje de deprecación
charmander.speak();