Fundamentos de TypeScript

1

¿Qué es TypeScript y por qué usarlo?

2

Instalación de Node.js y TypeScript CLI, configuración de tsconfig.json

3

Tipos primitivos: string, number, boolean, null, undefined de Typescript

4

Tipos especiales: any, unknown, never, void de TypeScript

5

Arrays, Tuplas, Enums en TypeScript

Funciones e Interfaces

6

Declaración de funciones, tipado de parámetros y valores de retorno

7

Parámetros opcionales, valores por defecto y sobrecarga de funciones

8

Creación y uso de interfaces de TypeScript

9

Propiedades opcionales, readonly, extensión de interfaces en TypeScript

Clases y Programación Orientada a Objetos

10

Creación de clases y constructores En TypeScript

11

Modificadores de acceso (public, private, protected) en Typescript

12

Uso de extends, sobreescritura de métodos en TypeScript

13

Introducción a Genéricos en Typescript

14

Restricciones con extends, genéricos en interfaces

Módulos y Proyectos

15

Importación y exportación de módulos en TypeScript

16

Agregando mi archivo de Typescript a un sitio web

17

Configuración de un proyecto Web con TypeScript

18

Selección de elementos, eventos, tipado en querySelector en TypeScript

19

Crear un proyecto de React.js con Typescript

20

Crea un proyecto con Angular y Typescript

21

Crea una API con Typescript y Express.js

Conceptos Avanzados

22

Introducción a types en TypeScript

23

Implementación de Decoradores de TypeScript

24

Async/await en Typescript

25

Pruebas unitarias con Jest y TypeScript

26

Principios SOLID, código limpio, patrones de diseño en Typescript

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de TypeScript

Curso de TypeScript

Amin Espinoza

Amin Espinoza

Implementación de Decoradores de TypeScript

23/26
Recursos

Los decoradores en TypeScript representan una poderosa herramienta para extender la funcionalidad de clases, métodos, propiedades y parámetros. Esta característica, aunque experimental, ofrece una forma elegante de transferir metadatos y añadir comportamientos adicionales a elementos existentes, siendo especialmente útil en frameworks como Angular donde la comunicación entre componentes es fundamental.

¿Qué son los decoradores en TypeScript?

Los decoradores son un patrón de diseño que permite añadir funcionalidades adicionales a elementos existentes sin modificar su estructura original. En TypeScript, se identifican fácilmente por el símbolo @ seguido del nombre del decorador.

Estos pueden implementarse en:

  • Clases
  • Métodos
  • Propiedades
  • Parámetros

La principal ventaja de los decoradores es que permiten transferir metadatos entre diferentes partes de tu aplicación, facilitando la comunicación entre componentes, especialmente en frameworks como Angular.

¿Cómo implementar un decorador de clase?

Para implementar un decorador de clase, necesitamos seguir estos pasos:

  1. Crear una función que servirá como implementación del decorador.
  2. Aplicar el decorador a la clase usando la sintaxis @nombreDecorador.
  3. Configurar el proyecto para soportar decoradores.

Veamos un ejemplo práctico:

// Implementación del decorador
function personaDeck(target: Function) {
  console.log(target);
  
  // Extendemos la funcionalidad añadiendo un nuevo método
  target.prototype.despedir = function(despedida: string): string {
    return despedida + " " + this.nombre;
  };
}

// Aplicación del decorador a la clase
@personaDeck
class Persona2 {
  nombre: string;
  edad: number;
  
  // Declaramos el método que será añadido por el decorador
  despedir!: (despedida: string) => string;
  
  constructor(nombre: string, edad: number) {
    this.nombre = nombre;
    this.edad = edad;
  }
  
  saludar(saludo: string): string {
    return `${saludo}, mi nombre es ${this.nombre} y tengo ${this.edad} años`;
  }
}

Es importante notar que la función del decorador debe definirse antes de usarla con la sintaxis @. De lo contrario, obtendremos un error en tiempo de ejecución.

¿Cómo habilitar los decoradores en un proyecto TypeScript?

Para utilizar decoradores en TypeScript, debemos habilitar la opción experimental en nuestro archivo de configuración tsconfig.json:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    // otras opciones...
  }
}

Puedes crear este archivo ejecutando el comando tsc --init en la terminal dentro de tu proyecto.

¿Por qué usar decoradores en lugar de otras técnicas?

Aunque existen otras formas de extender la funcionalidad de clases (como la herencia o las interfaces), los decoradores ofrecen ventajas únicas:

  1. Metadatos accesibles: Los metadatos pueden ser accedidos desde cualquier parte del proyecto, incluyendo archivos HTML.
  2. Comunicación eficiente: Facilitan la interacción entre diferentes componentes.
  3. Separación de responsabilidades: Permiten añadir funcionalidades sin modificar el código original.
  4. Integración con frameworks: Son especialmente útiles en frameworks como Angular, donde los decoradores como @Component son fundamentales.

Ejemplo práctico en Angular

En Angular, los decoradores son una parte esencial del framework. Por ejemplo, el decorador @Component permite definir metadatos para un componente:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Mi Aplicación Angular';
}

Este decorador establece la comunicación entre la clase TypeScript y su correspondiente plantilla HTML, facilitando el intercambio de datos y comportamientos.

Los decoradores en TypeScript pueden parecer complejos al principio, pero una vez que comprendes su funcionamiento, se convierten en una herramienta invaluable para crear código más limpio, modular y fácil de mantener. ¿Has utilizado decoradores en tus proyectos? Comparte tu experiencia en los comentarios y descubre cómo esta característica puede mejorar tu desarrollo con TypeScript.

Aportes 3

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

No creo haber escuchado en clases anteriores sobre los `prototype` este termino puede llegar a confunder a algunas personas sin ese contexto. <https://developer.mozilla.org/es/docs/Learn_web_development/Extensions/Advanced_JavaScript_objects/Object_prototypes> Espero 2 cosas haberme equivocado con mi comentario y si no que el enlace le sirva si no conocen acerca de los proptotype en JavaScript
Un decorador en JavaScript no es una característica nativa como en TypeScript, pero puedes simular su comportamiento utilizando funciones. Aquí hay un ejemplo simple: ```javascript function logger(target) { const originalMethod = target.prototype.sayHello; target.prototype.sayHello = function() { console.log('Antes de llamar a sayHello'); originalMethod.apply(this); console.log('Después de llamar a sayHello'); }; } @logger class Person { sayHello() { console.log('Hola, soy una persona'); } } const person = new Person(); person.sayHello(); ``` En este caso, `logger` actúa como un decorador que envuelve el método `sayHello` de la clase `Person`. Aunque esta sintaxis de decoradores no es parte del estándar de JavaScript, puedes utilizar funciones de orden superior para lograr un efecto similar.
Si alguien está utilizando Bun como lo estoy haciendo yo, puede que se le presente un problema al definir el decorador como lo explica el profe. Para corregir el error, el código es el siguiente: ```ts function PersonaDec<T extends { new (...args: any[]): {} }>(constructor: T) { console.log(constructor); return class extends constructor { despedir(despedida: string): string { return `${despedida}, ${(this as any).nombre}`; } }; } @PersonaDec class Persona { nombre: string; edad: number; constructor(nombre: string, edad: number) { this.nombre = nombre; this.edad = edad; } saludar(saludo: string): string { return `${saludo}, mi nombre es ${this.nombre} y tengo ${this.edad} años`; } despedir(despedida: string): string { return `${despedida}, ${this.nombre}`; } } ```function PersonaDec\<T extends { new (...args: any\[]): {} }>(constructor: T) { console.log(constructor); return class extends constructor { despedir(despedida: string): string { return `${despedida}, ${(*this* as any).nombre}`; } };} @PersonaDecclass Persona { nombre: string; edad: number; constructor(nombre: string, edad: number) { *this*.nombre = nombre; *this*.edad = edad; } saludar(saludo: string): string { return `${saludo}, mi nombre es ${*this*.nombre} y tengo ${*this*.edad} años`; } despedir(despedida: string): string { return `${despedida}, ${*this*.nombre}`; }}