En TypeScript estricto, el error capturado en un catch es de tipo unknown:
Para usar el error, primero debes verificar su tipo:
Esto es tedioso y se repite en cada catch.
Una alternativa elegante es el patrón Result: en vez de lanzar errores, devuelves un objeto que indica éxito o fallo.
Es una discriminated union con ok como discriminante:
| throw/catch | Result | |
|---|---|---|
| Errores visibles en firma | No — no sabes si una función puede lanzar | Sí — el retorno dice Result |
| TypeScript ayuda | Poco — error es unknown | Mucho — narrowing automático |
| Flujo de control | Salta al catch más cercano | Flujo lineal, predecible |
| Cuándo usar | Errores inesperados (bugs) | Errores esperados (validación, negocio) |
La regla: usa throw para errores inesperados (el servidor se cayó, un bug). Usa Result para errores que esperas (datos inválidos, usuario no encontrado).
Puedes hacer el error más específico:
Cada paso devuelve un Result. Si algo falla, el error se propaga limpiamente.
Tienes el tipo Result<T> definido. Crea:
dividir(a, b) que devuelva Result<number> — error si b es 0buscarUsuario(id) que devuelva Result<{ nombre: string }> — error si id < 0if (resultado.ok)El patrón Result hace que los errores sean ciudadanos de primera clase en tu sistema de tipos. No más errores que se escapan silenciosamente.