← Volver al blog Post

Composición de tipos en TypeScript

Publicado originalmente en Lean Mind.

Introducción

Uno de los puntos fuertes de TypeScript es la flexibilidad que brinda al definir estructuras de datos. Pero esa misma flexibilidad también puede convertirse en una fuente importante de problemas si se utiliza sin suficiente precisión.

El problema

El ejemplo parte de un tipo UserAddress que inicialmente parecía suficiente para representar la dirección de una persona usuaria. Con el tiempo surgieron nuevos requisitos: la dirección podía ser de billing o de shipping, y esta última además podía ser física o digital.

La solución rápida fue convertir muchas propiedades en opcionales para cubrir todos los casos con un único tipo. El problema es que eso abre la puerta a estados imposibles y errores extraños, como tener datos propios de un envío físico en un caso de envío digital.

La solución: ser más específicos

En lugar de generalizar en exceso, la propuesta es descomponer el problema:

  • Customer para los datos básicos de la persona.
  • UserDigitalAddress para los casos donde hay activationEmail.
  • UserPhysicalAddress para los casos donde existe una Address física.
  • UserDigitalPhysicalAddress para los casos mixtos.

Después podemos componer esos tipos con Omit, intersecciones y uniones para obtener restricciones más precisas y expresivas.

Resultado

La clave no es usar tipos avanzados por sí mismos, sino aprovecharlos para impedir casos imposibles y hacer el código más semántico. En vez de llenar todo de propiedades opcionales, definimos estructuras que reflejen con más fidelidad las reglas del dominio.

Conclusión

La composición de tipos no es una solución universal, pero en muchos casos ayuda a protegernos de errores derivados de estructuras demasiado permisivas. Como resultado, el código se vuelve más expresivo y el propio sistema de tipos nos acompaña durante el desarrollo para reforzar el comportamiento esperado.

  • typescript
  • type-systems
  • design