Decoradores en TypeScript
Este artículo explica los decoradores en TypeScript.
YouTube Video
Decoradores en TypeScript
Los decoradores en TypeScript son un mecanismo para añadir funcionalidad o comportamiento adicional a clases, métodos, accesores, propiedades o parámetros. Los decoradores son una herramienta poderosa para mejorar la legibilidad y reutilización del código.
Fundamentos de los Decoradores
Un decorador es una función que inyecta funcionalidad adicional en una clase o miembros de la misma. Los decoradores fueron introducidos en TypeScript 1.5 y también han sido propuestos para el estándar ECMAScript.
1{
2 "compilerOptions": {
3 "experimentalDecorators": true
4 }
5}
- Para usar decoradores, necesitas habilitar la opción
experimentalDecorators
en el archivotsconfig.json
.
Tipos de Decoradores
En TypeScript, puedes usar los siguientes cinco decoradores.
- Decorador de Clase Un decorador aplicado a una clase.
- Decorador de Método Un decorador aplicado a un método de una clase.
- Decorador de Accesor Un decorador aplicado a un getter o setter de una propiedad de clase.
- Decorador de Propiedad Un decorador aplicado a una propiedad de una clase.
- Decorador de Parámetro Un decorador aplicado a un parámetro de un método.
Decorador de Clase
Los decoradores de clase son decoradores aplicados a clases. Los decoradores de clase se escriben justo encima de la definición de la clase y pueden acceder al constructor de la clase. Principalmente se usan para cambiar el comportamiento de la clase o para añadir metadatos.
1function Logger(constructor: Function) {
2 console.log(`Class ${constructor.name} is being constructed`);
3}
4
5@Logger
6class Person {
7 constructor(public name: string) {}
8}
9
10const person = new Person('John');
11// Output: Class Person is being constructed
En este ejemplo, el decorador Logger
se aplica a la clase, y se muestra un mensaje en la consola cuando se inicializa la clase.
Decorador de Método
Los decoradores de método se aplican a los métodos de clase y pueden alterar las llamadas y el comportamiento de los métodos. Un decorador de método toma tres argumentos.
- El prototipo de la clase
- El nombre del método
- El descriptor de la propiedad del método
1function LogExecutionTime(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalMethod = descriptor.value;
3
4 descriptor.value = function (...args: any[]) {
5 console.time(propertyKey);
6 const result = originalMethod.apply(this, args);
7 console.timeEnd(propertyKey);
8 return result;
9 };
10}
11
12class MathOperations {
13 @LogExecutionTime
14 add(a: number, b: number): number {
15 return a + b;
16 }
17}
18
19const math = new MathOperations();
20math.add(2, 3);
21// Output: add: 0.000ms (execution time is displayed)
En este ejemplo, el decorador LogExecutionTime
se aplica al método y se registra el tiempo de ejecución del método.
Decorador de Accesor
Los decoradores de acceso se aplican al getter
o setter
de las propiedades de clase. Son útiles para añadir comportamiento al cambiar los valores de las propiedades.
1function LogAccess(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalGet = descriptor.get;
3 const originalSet = descriptor.set;
4
5 if (originalGet) {
6 descriptor.get = function () {
7 console.log(`Getter called for ${propertyKey}`);
8 return originalGet.call(this);
9 };
10 }
11
12 if (originalSet) {
13 descriptor.set = function (value: any) {
14 console.log(`Setter called for ${propertyKey} with value: ${value}`);
15 originalSet.call(this, value);
16 };
17 }
18}
19
20class Car {
21 private _speed: number = 0;
22
23 @LogAccess
24 get speed() {
25 return this._speed;
26 }
27
28 set speed(value: number) {
29 this._speed = value;
30 }
31}
32
33const car = new Car();
34car.speed = 120; // Setter called for speed with value: 120
35console.log(car.speed); // Getter called for speed → 120
En este ejemplo, se utiliza un decorador de acceso para registrar la salida cuando se llaman el getter
y el setter
.
Decorador de Propiedad
Los decoradores de propiedad se aplican a las propiedades de clase pero no pueden cambiar directamente el valor o comportamiento de la propiedad. Se utilizan para obtener metadatos de las propiedades.
1function Readonly(target: any, propertyKey: string) {
2 Object.defineProperty(target, propertyKey, {
3 writable: false
4 });
5}
6
7class Book {
8 @Readonly
9 title: string = "TypeScript Guide";
10}
11
12const book = new Book();
13book.title = "New Title"; // Error: Cannot assign to read only property 'title'
En este ejemplo, el decorador Readonly
se aplica a la propiedad title
, y la propiedad se hace de solo lectura.
Decorador de Parámetro
Los decoradores de parámetros se aplican a los parámetros de un método. Generalmente se utilizan para almacenar metadatos o validar parámetros. Los decoradores reciben tres argumentos.
- El prototipo de la clase
- El nombre del método
- Índice del Parámetro
1function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
2 console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} was decorated.`);
3}
4
5class User {
6 greet(@LogParameter message: string) {
7 console.log(message);
8 }
9}
10
11const user = new User();
12user.greet('Hello!');
13// Output: Parameter at index 0 in method greet was decorated.
En este ejemplo, el decorador LogParameter
se aplica al primer parámetro del método greet
, y cuando se llama al método, se registra que el parámetro está decorado.
Ejemplos Prácticos de Decoradores
Los decoradores se utilizan ampliamente en frameworks como Angular, especialmente para la inyección de dependencias y la definición de metadatos. Por ejemplo, utiliza el decorador @Component
para definir componentes de Angular como se muestra a continuación.
1@Component({
2 selector: 'app-root',
3 template: '<h1>Hello World</h1>',
4})
5export class AppComponent {}
Por lo tanto, los decoradores suelen usarse como partes fundamentales de frameworks y librerías, ayudando a mantener el código conciso y claro.
Resumen de los Decoradores
Los decoradores de TypeScript son herramientas poderosas que añaden funcionalidad de manera flexible a clases, métodos y propiedades. Usar decoradores personalizados mejora el mantenimiento y la reutilización del código, permitiendo una mayor abstracción. Los decoradores desempeñan un papel importante en frameworks como Angular y NestJS, y entenderlos ayuda a comprender en profundidad cómo funcionan estos frameworks.
Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.