Al principio añadía tipos como quien completa un formulario: string aquí, number allá. El cambio llegó cuando intenté representar una petición remota sin permitir combinaciones imposibles, como tener un error y datos válidos al mismo tiempo.
Modelar estados, no banderas
tsarchivo local
type RequestState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; message: string };Las uniones discriminadas hicieron que el autocompletado y el compilador funcionaran como una revisión temprana del diseño. También redujeron condicionales defensivos dentro de los componentes.