Librería neverthrow para TypeScript: Result type para el manejo de errores
1. ¿Qué es y para qué sirve?
En el desarrollo moderno con TypeScript, el manejo de errores a menudo se convierte en un caos de bloques try/catch dispersos por todo el código. La librería neverthrow ofrece una solución elegante a este problema, inspirada en lenguajes de programación funcionales como Rust y Haskell. Proporciona el tipo Result<T, E>, que representa explícitamente un resultado exitoso (Ok) o un error (Err), haciendo que el manejo de errores sea parte del sistema de tipos, no un efecto secundario.
El objetivo principal de neverthrow es reemplazar las excepciones implícitas con tipos explícitos. En lugar de escribir una función que pueda lanzar una excepción en cualquier momento, devuelves un Result que el compilador de TypeScript te obligará a manejar. Esto hace que el código sea más predecible, seguro y autodocumentado. Ya no tienes que adivinar qué funciones pueden lanzar un error: el tipo de retorno te lo dice directamente.
La librería es especialmente útil en proyectos donde la fiabilidad es clave: servicios backend, aplicaciones financieras, sistemas de procesamiento de datos. También se combina muy bien con otros conceptos funcionales como los tipos Option (Maybe) y se puede integrar con librerías como fp-ts. neverthrow no es solo una utilidad, es una filosofía de escritura de código donde los errores son datos, no situaciones excepcionales.
2. Instalación
Instalación de neverthrow en un proyecto TypeScript/NPM:
npm install neverthrow
Para proyectos que usan yarn:
yarn add neverthrow
Para pnpm:
pnpm add neverthrow
La librería está escrita en TypeScript e incluye tipos completos, por lo que no es necesaria la instalación adicional de @types. Después de la instalación, puedes importar los tipos y funciones principales:
import { ok, err, Result } from 'neverthrow';
3. Inicio rápido — ejemplo mínimo funcional
Vamos a crear una función simple que divide dos números, pero devuelve un Result en lugar de lanzar una excepción al dividir por cero:
import { ok, err, Result } from 'neverthrow';
// Definimos el tipo de error
type DivisionError = { message: string; code: number };
// Función que devuelve un Result
function safeDivide(a: number, b: number): Result<number, DivisionError> {
if (b === 0) {
return err({ message: 'División por cero', code: 1001 });
}
return ok(a / b);
}
// Uso
const result = safeDivide(10, 2);
// Manejo del resultado
if (result.isOk()) {
console.log('Resultado:', result.value); // Resultado: 5
} else {
console.error('Error:', result.error.message); // Nunca se ejecutará
}
const errorResult = safeDivide(10, 0);
if (errorResult.isErr()) {
console.error('Error:', errorResult.error.message); // Error: División por cero
}
Este ejemplo demuestra la idea principal: la función siempre devuelve un Result, y el código que la llama debe verificar si el resultado es exitoso antes de usar el valor. El compilador de TypeScript no te permitirá acceder a result.value sin la verificación correspondiente.
4. Métodos/funciones/clases principales
4.1. ok(value) — Creación de un resultado exitoso
Firma:
function ok<T, E = never>(value: T): Ok<T, E>
Qué hace: Crea una instancia de Ok que representa un resultado exitoso con el valor proporcionado.
Ejemplo:
import { ok } from 'neverthrow';
const success = ok(42);
console.log(success.isOk()); // true
console.log(success.value); // 42
4.2. err(e
También en la biblioteca
Kysely para TypeScript: guía completa con ejemplos prácticos
Cliente HTTP para JavaScript (Node.js): top bibliotecas para trabajar con API
React para JavaScript (Node.js): guía completa con ejemplos
Codable Swift: guía completa con ejemplos prácticos