Itequia

TypeScript y React para proyectos con IA: eficiencia en frontend y backend

Typescript y React

Construir aplicaciones con IA no es solo conectar una API y renderizar texto. Se trata de gestionar incertidumbre. Respuestas que llegan por partes, estructuras que cambian, errores que no se parecen a los de un backend convencional, etc. TypeScript y React, bien combinados, son una de las respuestas más sólidas a ese reto. A lo largo de este artículo desgranamos cómo abordar los principales retos que aparecen al construir este tipo de aplicaciones.

El problema del tipado cuando la IA genera datos no deterministas

Los modelos de lenguaje no devuelven siempre la misma estructura. Una respuesta puede incluir campos opcionales, arrays vacíos o texto libre donde esperabas un objeto. Sin tipado, esos casos se convierten en errores silenciosos en producción.

TypeScript obliga a definir contratos explícitos entre el modelo y la aplicación. Para respuestas de LLMs con structured outputs o tool calls, una combinación de zod para validación en runtime y tipos derivados con z.infer<> cubre bien la mayoría de casos:

image.jpeg

Esto no elimina la imprevisibilidad del modelo, pero sí la contiene. Si la respuesta no encaja con el esquema, el error es explícito y controlado. No un undefined is not a function tres capas más abajo.

Gestión de estado en React cuando la fuente de datos es un modelo de IA

El streaming de tokens rompe el modelo mental habitual de “petición → respuesta”. El estado no es binario (cargando / listo), tiene fases: conectando, recibiendo, completado, cancelado y error parcial.

useReducer encaja mejor que useState para este tipo de máquinas de estado:

image-1.jpeg

Para cancelación, la Streams API con AbortController es el enfoque estándar. TanStack Query añade valor en flujos con caché o revalidación. Sin embargo, para streaming puro, a veces es más directo manejar el estado localmente. Lo importante es modelar explícitamente los estados intermedios en lugar de colapsarlos en un booleano isLoading.

Arquitectura frontend-backend con TypeScript end-to-end

Cuando el backend también es TypeScript, compartir tipos entre cliente y servidor elimina una categoría entera de bugs. Dos aproximaciones habituales:

  • Monorepo con paquete compartido. Un packages/types que importan tanto el frontend como el backend. Simple y directo.
  • tRPC. Define los endpoints como funciones tipadas en el servidor y el cliente los consume con autocompletado completo. Sin necesidad de generar código.

En proyectos con múltiples integraciones de IA, donde los contratos entre capas cambian con frecuencia, esta coherencia end-to-end reduce drásticamente el tiempo de depuración. Un cambio en el tipo de respuesta del modelo se propaga como error de compilación antes de llegar a producción.

NestJS como backend para orquestar modelos e integraciones de IA

NestJS aporta estructura donde los proyectos de IA tienden al caos. La inyección de dependencias permite encapsular la lógica de cada proveedor (Anthropic, OpenAI, modelos propios) en servicios intercambiables:

image-2.jpeg

Esto hace los servicios de IA testables de forma aislada y desacoplados del resto de la aplicación. La gestión de contexto de conversación, memoria y prompt templates encaja bien en este modelo. Un ConversationService que acumula el historial, un PromptBuilder que construye el mensaje final y el controlador HTTP que los coordina.

Testing de componentes React que consumen IA

Mockear un LLM en tests no es opcional. Las respuestas reales son lentas, variables y de pago. La estrategia más útil es separar por capas:

  • Tests unitarios: mockear el servicio de IA con respuestas predefinidas. Probar que el componente renderiza correctamente ante una respuesta lenta, un error de rate limit o contenido inesperado.
  • Tests de integración: usar un servidor mock (MSW funciona bien) que simule el streaming token a token.
  • Tests end-to-end con Playwright: interceptar las llamadas a la API real y sustituirlas por fixtures. Esto permite validar flujos completos sin depender de la disponibilidad del modelo.

El caso más importante para cubrir no es el happy path, sino cómo se comporta la UI cuando la respuesta llega en 8 segundos, llega a medias o no llega.

Rendimiento en interfaces con streaming y respuestas en tiempo real

Renderizar cada token como un re-render de React es el camino más corto a una UI bloqueada. Te explicamos algunas técnicas que marcan la diferencia:

  • Batching de updates. Acumular tokens en un buffer y actualizar el estado cada ~100ms en lugar de en cada token recibido.
  • useDeferredValue. Para separar la actualización del input de la del contenido renderizado.
  • Virtualización. En conversaciones largas, react-virtual o TanStack Virtual evitan renderizar mensajes que no están en el viewport.
  • Memoización selectiva. React.memo en los mensajes históricos que ya no van a cambiar.

El cuello de botella rara vez está en JavaScript puro. Casi siempre está en cuántas veces React decide que necesita re-renderizar el árbol completo.

TypeScript y React en proyectos de modernización con IA

Esta combinación no solo es válida para proyectos nuevos. En migraciones de aplicaciones legacy, TypeScript actúa como red de seguridad. Permite introducir módulos de IA de forma incremental sin romper el resto del sistema. Los tipos documentan los contratos implícitos que en el código legado solo existían en la cabeza de quien lo escribió.

Conectado con el resto de la cadena de modernización (documentación automática de APIs, automatización con Power Automate y testing con Playwright) TypeScript end-to-end es el tejido conectivo que hace que las piezas se hablen entre sí sin fricciones.

Si estás evaluando cómo introducir IA en tu stack o modernizar una aplicación existente, contacta con nosotros. Podemos hacer una revisión inicial para identificar los puntos de entrada más adecuados en tu caso.