better-result for typed TypeScript errors
Notes on better-result, a TypeScript Result library with tagged errors, generator composition, explicit defect handling, and schema-aware boundaries.
Notes on better-result, a TypeScript Result library with tagged errors, generator composition, explicit defect handling, and schema-aware boundaries.
better-result is a TypeScript library for making expected failures part of function return types instead of hiding them behind exceptions.
Core type is familiar: Result<T, E> is either Ok<T> or Err<E>. Library has no runtime dependencies, requires TypeScript 5.4+, and is ESM-only.
TaggedError gives errors useful structure. Errors are real Error subclasses but also have literal _tag values and typed properties. This makes error unions easy to narrow and match without depending only on instanceof.
Result.gen makes composition less noisy. Multiple fallible operations can use yield* and read like normal sequential code. First Err stops workflow, while TypeScript keeps inferred union of possible errors. This avoids long andThen chains while keeping failure types visible.
Expected errors and defects stay separate. Recoverable cases belong in Err. Unexpected throws inside Result callbacks become Panic. This prevents programmer bugs and broken invariants from silently becoming another domain error variant.
Throwing APIs have explicit adapters. Result.try and Result.tryPromise convert exceptions into Results. Async version also supports retry policies, backoff, jitter, and cancellation.
Result values can cross boundaries. Result.codec uses Standard Schema-compatible validators for serialization and deserialization. This looks useful around RPC, persistence, queues, or server actions where in-memory types are not enough.
Main question is whether generator-based composition stays readable in a larger codebase, especially when mixed with existing code that throws exceptions or already has its own error conventions.
Still, better-result looks worth keeping as a reference when I need typed domain errors without moving to a much larger effect system.