🇺🇸 EN
Frontend
·3 min read·↗·🇺🇸 EN

Cómo usar decoradores de clases en TypeScript con un ejemplo real

Portada principal del artículo: Cómo usar decoradores de clases en TypeScript con un ejemplo real

Los decoradores son una excelente característica de TypeScript; seguro los has visto por todas partes en Angular y en otros frameworks.

Nos ayudan a escribir código limpio y declarativo. Es muy probable que ya los utilices a diario, pero ¿sabes cuándo crear tus propios decoradores?

En este artículo te muestro cómo crear tus decoradores y cómo implementarlos.

¿Qué es un decorador?

Un decorador es una función que podemos conectar a nuestro código para extenderlo con cierto comportamiento. Nos ayuda a escribir abstracciones para mantener el código claro.

La función del decorador varía según lo que vayas a decorar. Esto significa que no recibe los mismos parámetros cuando trabajas sobre una clase, un método o una propiedad.

¿Dónde puedo usar decoradores?

Los decoradores nos ayudan en varias partes del código de una clase:

  • Definición de clases
  • Propiedades
  • Métodos
  • Accesores (getters y setters)
  • Parámetros

Mi primer decorador de clase

Los decoradores de clase reciben la función constructora como parámetro, lo que significa que podemos modificar la forma en que inicializamos la clase.

Te muestro un caso sencillo: supongamos que tenemos varias clases de entidades y cada una necesita tener las propiedades id y created. La solución habitual es crear una clase base.

class BaseEntity {
  readonly id: number;
  readonly created: string;
  constructor() {
    this.id = Math.random();
    this.created = new Date().toLocaleDateString();
  }
}

La clase Course extiende de BaseEntity y llama al constructor con super().

class Course extends BaseEntity {
  constructor(public name: string) {
    super();
  }
}
 
let englishCourse = new Course("English");
console.log("id: " + englishCourse.id);
console.log("created: " + englishCourse.created);

Funciona perfecto. Pero, ¿cómo podemos resolver esto mismo usando decoradores?

El decorador

El decorador de clase es una función que recibe el constructor como parámetro, en el que podemos agregar las propiedades id y created.

function BaseEntity(ctr: Function) {
  ctr.prototype.id = Math.random();
  ctr.prototype.created = new Date().toLocaleString("es-ES");
}

El decorador ya está listo para usarse en cada entidad sin necesidad de modificar su constructor ni usar herencia con extends. Solo necesitamos agregar @BaseEntity antes de la definición de la clase.

@BaseEntity
class User {
  constructor(public name: string) {}
}
 
@BaseEntity
class City {
  constructor(public zicode: number) {}
}
 
let user = new User("dany");
let ny = new City("RD");
// Las clases City y User tienen las propiedades id y created ;)
console.log(ny.id);
console.log(user.id);

Factoría de decoradores (Decorator Factory)

Una factoría de decoradores es una función que retorna la propia función decoradora. Esto nos da la flexibilidad de pasar parámetros a nuestros decoradores.

Por ejemplo, queremos que la nueva propiedad sea un número aleatorio entre 0 y el valor que pasemos por parámetro:

function LuckyNumber(limit: number) { 
  return function (constructor: Function) { 
    constructor.prototype.lucky = Math.floor(
      Math.random() * Math.floor(limit)
  }
}

El decorador LuckyNumber recibe un número como parámetro para definir el límite del rango y podemos combinarlo con nuestra entidad base:

@BaseEntity
@LuckyNumber(3)
class User {
  constructor(public name: string) {}
}
 
@BaseEntity
@LuckyNumber(3)
class City {
  constructor(public zicode: number) {}
}
 
let user = new User("dany");
let ny = new City(08930);
// City y User tienen la propiedad lucky
console.log(ny.lucky);
console.log(user.lucky);

Los decoradores nos ayudan a agregar comportamiento y metadatos a clases, métodos o propiedades de una forma declarativa.

Resumen

Espero que esto te sirva para entender cómo y cuándo usar decoradores de clases en TypeScript. Si te gustó este artículo, ¡compártelo!

Photo by Ferenc Almasi on Unsplash

Parte de la serie Frontend

Modern frontend development — Angular, React, TypeScript, accessibility, and performance.

Ver serie completa

Artículos Relacionados

Compartir este artículo

Si esta guía te resultó útil, compártela con tu equipo o con otros desarrolladores.


Software real. Lecciones reales.

Comparto las lecciones que aprendí por las malas, para que puedas evitarlas o estar preparado cuando ocurran.

User avatar
User avatar
User avatar
User avatar
+13K

Únete a 13,800+ desarrolladores y lectores.

Cero spam. Cancela tu suscripción en cualquier momento.