Pasar al contenido principal
Cargando...

TypeScript 5.0

Inspiring technology by Hunters

Nuestros Hunters, cazadores de tendencias tecnológicas, nunca paran. En esta nueva edición de Inspiring Technology nos hablan de Decorators, dentro de TypeScript 5.0. ¡Sigue leyendo!

En el lanzamiento de TypeScript 5.0 se ha incluido un nuevo estándar para el uso de Decorators. Los Decorators son una funcionalidad de TypeScript que permiten modificar el comportamiento de clases y sus miembros de un modo reutilizable. Están basados en el patrón de diseño homónimo, que explicamos en este artículo.

Descubriendo el patrón de diseño Decorator

El patrón de diseño Decorator es un patrón de diseño estructural que permite añadir funcionalidades dinámicamente a un objeto base. Esta adición de funcionalidades se realiza envolviendo el objeto base en un objeto encapsulador que aporta los comportamientos añadidos.

Como ejemplo del patrón Decorator, se podría plantear una interfaz con la que se muestra un documento como la siguiente:

patrón Decorator

Y se podría utilizar el patrón Decorator para agregarle la funcionalidad de presentar el documento con distintos formatos de la siguiente forma:

decorator

Principales características y usos

Los Decorators en TypeScript pueden ser utilizados sobre componentes como propiedades/campos, getters, setters, métodos de clase, clases y auto-accessors, que explicaremos más adelante. Un Decorator puede realizar hasta cuatro funciones, dependiendo del tipo de componente sobre el que se aplique:

  • Realizar cambios en la entidad a decorar.
  • Reemplazar la entidad a decorar por otra del mismo tipo.
  • Exponer acceso a la entidad a decorar a terceros.
  • Procesar la entidad a decorar y su contenedor (si lo tiene), por ejemplo, un método de clase y dicha clase.

Por otra parte, un Decorator puede ser aplicado a múltiples componentes y puede recibir parámetros, por lo que es posible cambiar su comportamiento dependiendo del componente sobre el que se use.

¿Dónde se pueden aplicar los Decorators?

Un ejemplo sencillo de aplicación de los Decorators podría ser el uso de estos para hacer logs cuando métodos de clase son ejecutados.

Para ello, como se puede ver en la siguiente imagen, se declaran un par de clases con métodos, que se anotan con la etiqueta “@log” para indicar que dichos métodos deben ser decorados aplicando el decorator “log”.

Typescript

Posteriormente, se declara el decorator log:

Typescript

​​​​Este método recibe como parámetros el método original y un objeto context, que contiene varios datos sobre el contexto en el que se ejecuta el método decorator (en este caso se utiliza el nombre del método original para mostrarlo). El método devuelve una función que ejecuta instrucciones antes y después de realizar la llamada al método original.

Por último, si ejecutamos las funciones anotadas con “@log” de la siguiente forma:

Obtenemos el siguiente resultado: 

Por otra parte, con los Decorators se podrían validar datos de propiedades/campos de una clase. Sin embargo, puesto que la inicialización de los datos (init/constructor) y la asignación de estos (set) se realizan distintamente, sería preciso definir un decorator para cada una de estas funcionalidades. Para simplificar este tipo de implementación, los auto-accesors serán nuestros mejores aliados.

Pero... ¿qué son los auto-accesors?

Los auto-accessors son una nueva característica del lenguaje TypeScript, añadida en la versión 4.9, similares a los campos de una clase, pero que difiere en su implementación en tiempo de ejecución. Debido a la diferencia en tiempo de ejecución es posible decorar fácilmente tanto la inicialización de datos como la asignación y obtención de ellos.
 

Para ilustrar este caso se plantea el siguiente ejemplo, donde se valida que el número proporcionado no sea menor que 0:

Para empezar, se define una clase con un auto-accesor en lugar de un campo tradicional. Para ello se utiliza la palabra accessor antes de la definición del campo.

Se anota el auto-accessor con la etiqueta “@minimumNumber0” para aplicar el decorator. Por último, se define el decorator de la siguiente forma: 

Como se puede ver, el decorator recibe los inicializadores, getters y setters originales del auto- accesor, define la función con la que se validarán los valores del campo y aplica la función en los inicializadores y setters decorados. Como no se requiere nada en el getter, simplemente devuelve la llamada original.

Si ahora se intentan proporcionar valores al auto-accesor “age” de la siguiente forma:

Se obtienen los siguientes resultados:

Finalmente, se podría parametrizar el decorator para que reciba el valor mínimo en lugar de fijarlo a 0. Esto se conseguiría implementando una Decorator Factory.

Decorator Factory

Una Decorator Factory permite proporcionarle parámetros a un Decorator para alterar su comportamiento.

Para parametrizar el Decorator utilizado en el ejemplo anterior, bastaría con envolver el decorator en una función que reciba un parámetro, como se puede observar en la siguiente imagen:

Además, sería necesario añadir el valor mínimo como parámetro a la etiqueta con la que se llama al Decorator:

Conclusiones

Los Decorators son herramientas que pueden ayudar a la reutilización de código y a aumentar la claridad de este. También permiten implementar funcionalidades distintas de las que han sido descritas, como por ejemplo inyección de dependencias y control de acceso a entidades, por lo que se puede observar que son herramientas con potentes y diversas capacidades.

Por otra parte, dependiendo de las tareas para las que se pretendan utilizar, es posible que la complejidad de su implementación aumente, por lo que en ciertos casos pueden no resultar la mejor opción.

¿Quieres saber más sobre Hunters?

Ser un hunter es aceptar el reto de probar nuevas soluciones que aporten resultados diferenciales. Únete al programa Hunters y forma parte de un grupo transversal con capacidad de generar y transferir conocimiento.

Anticípate a las soluciones digitales que nos harán crecer. Consulta más información sobre Hunters.