TypeScript Avanzado: Patrones Genéricos y Tipado Profundo para Arquitecturas Complejas

Implementar el Patrón Factory con Tipos Genéricos

Concepto claveEl Patrón Factory es un patrón de diseño creacional que proporciona una interfaz para crear objetos en una superclase, permitiendo a las subclases alterar el tipo de objetos que se crearán. En TypeScript, combinarlo con tipos genéricos eleva su potencia, permitiendo crear fábricas que producen objetos con tipos específicos y seguros en tiempo de compilación.Imagina una fábrica de vehículos: tienes una línea de ensamblaje (la fábrica) que puede producir coches, motos o camiones. En
Tiempo de estudio
20 Min

Concepto clave

El Patrón Factory es un patrón de diseño creacional que proporciona una interfaz para crear objetos en una superclase, permitiendo a las subclases alterar el tipo de objetos que se crearán. En TypeScript, combinarlo con tipos genéricos eleva su potencia, permitiendo crear fábricas que producen objetos con tipos específicos y seguros en tiempo de compilación.

Imagina una fábrica de vehículos: tienes una línea de ensamblaje (la fábrica) que puede producir coches, motos o camiones. En lugar de construir cada vehículo manualmente, delegas la creación a la fábrica, que sabe los detalles específicos. Con TypeScript, añades un contrato de tipos: "esta fábrica solo produce vehículos con ruedas y motor", garantizando que cada objeto creado cumpla ciertas propiedades.

La clave aquí es la abstracción: separas la lógica de creación del uso del objeto. Esto es crucial en arquitecturas complejas, como en librerías o frameworks, donde necesitas flexibilidad para extender funcionalidades sin modificar código existente. Los genéricos permiten parametrizar los tipos de retorno, haciendo el código más reutilizable y type-safe.

Cómo funciona en la práctica

Implementar el Patrón Factory con TypeScript implica definir una interfaz o clase base para los productos, una fábrica abstracta que declare el método de creación, y fábricas concretas que implementen ese método. Los genéricos entran para tipar los productos de manera dinámica.

Paso a paso:

  1. Define una interfaz genérica para el producto. Por ejemplo: interface Product { id: T; name: string; }.
  2. Crea una clase abstracta o interfaz para la fábrica, usando genéricos para especificar el tipo de producto: abstract class Factory { abstract createProduct(config: T): U; }.
  3. Implementa fábricas concretas que extiendan la fábrica abstracta, proporcionando tipos específicos. Por ejemplo: class CarFactory extends Factory { createProduct(config: CarConfig): Car { return new Car(config); } }.
  4. Usa la fábrica en tu código: const factory = new CarFactory(); const car = factory.createProduct({ model: 'Sedan' });. TypeScript inferirá que car es de tipo Car.

Ejemplo con datos en una tabla:

Tipo de FábricaProducto GeneradoTipo Genérico
CarFactoryCarFactory
BikeFactoryBikeFactory
GenericFactoryT (genérico)Factory
En TypeScript avanzado, los genéricos en el Patrón Factory no solo mejoran la seguridad de tipos, sino que permiten crear arquitecturas escalables donde nuevas fábricas y productos se integran sin romper el sistema existente.

Caso de estudio

Considera un sistema de notificaciones para una aplicación frontend compleja. Necesitas enviar diferentes tipos de notificaciones: email, push y SMS. Cada notificación tiene propiedades específicas, pero todas comparten una interfaz común.

Implementación:

interface Notification {
type: string;
content: T;
send(): void;
}

abstract class NotificationFactory {
abstract createNotification(content: T): Notification;
}

class EmailNotification implements Notification {
type = 'email';
constructor(public content: string) {}
send() { console.log(`Enviando email: ${this.content}`); }
}

class EmailFactory extends NotificationFactory {
createNotification(content: string): Notification {
return new EmailNotification(content);
}
}

// Uso en la arquitectura
const emailFactory = new EmailFactory();
const notification = emailFactory.createNotification('Nuevo mensaje');
notification.send(); // TypeScript sabe que notification es Notification

Este caso muestra cómo el patrón, con genéricos, permite agregar nuevos tipos de notificaciones (ej., push con contenido JSON) sin modificar el código cliente, manteniendo el tipado estricto.

Errores comunes

  • No usar genéricos cuando se necesitan tipos flexibles: Si defines fábricas con tipos concretos, pierdes reutilización. En su lugar, parametriza con genéricos para adaptarte a diferentes productos.
  • Ignorar la inferencia de tipos de TypeScript: A veces, los desarrolladores especifican tipos manualmente donde TypeScript puede inferirlos, añadiendo complejidad innecesaria. Confía en la inferencia para mantener el código limpio.
  • Crear fábricas demasiado complejas: Evita añadir lógica de negocio en las fábricas; su único rol debe ser la creación de objetos. Si la fábrica hace más, viola el principio de responsabilidad única.
  • No manejar errores en la creación: En escenarios reales, la creación puede fallar (ej., datos inválidos). Incluye validaciones o usa tipos como Result para manejar errores de forma type-safe.
  • Olvidar cerrar el ciclo de tipos con interfaces: Asegúrate de que los productos implementen interfaces claras, o TypeScript no podrá garantizar la seguridad de tipos en usos avanzados.

Checklist de dominio

  1. ¿Puedes definir una interfaz genérica para un producto y una fábrica abstracta que la use?
  2. ¿Implementas fábricas concretas con genéricos que devuelvan tipos específicos sin usar any?
  3. ¿Utilizas el patrón para desacoplar la creación del uso en al menos un escenario real?
  4. ¿Manejas casos edge, como configuraciones inválidas, manteniendo la seguridad de tipos?
  5. ¿Eres capaz de extender el sistema añadiendo una nueva fábrica sin modificar código existente?
  6. ¿Aplicas principios SOLID, especialmente el de responsabilidad única, en tu implementación?
  7. ¿Documentas los tipos genéricos para que otros desarrolladores entiendan el contrato?

Implementa una Fábrica de Componentes UI con TypeScript Genérico


En este ejercicio, crearás un sistema de fábrica para componentes UI en una aplicación frontend. Sigue estos pasos:

  1. Define una interfaz genérica UIComponent con propiedades: id: string, props: T, y un método render(): string.
  2. Crea una clase abstracta ComponentFactory con un método abstracto createComponent(props: T): UIComponent.
  3. Implementa dos fábricas concretas: ButtonFactory para crear botones (con props de tipo ButtonProps que incluyan label: string y onClick: () => void) y InputFactory para campos de entrada (con props de tipo InputProps que incluyan placeholder: string y value: string).
  4. En cada fábrica concreta, implementa el método createComponent para devolver una instancia de un componente que implemente UIComponent.
  5. Escribe un código de ejemplo que use ambas fábricas para crear componentes y llame a su método render, mostrando el resultado en consola.
  6. Asegúrate de que TypeScript infiera los tipos correctamente y no uses any.

Pistas
  • Usa tipos genéricos en la interfaz UIComponent para parametrizar las props.
  • Define tipos específicos para ButtonProps e InputProps usando interfaces.
  • En las fábricas concretas, especifica los tipos genéricos al extender ComponentFactory.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Texto Leccion 1/20
Estas viendo
Implementar el Patrón Factory con Tipos Genéricos
Hablar por WhatsAppContactar por WhatsApp