The Result pattern replaces thrown exceptions with typed return values. It's a discriminated union — a union type with a shared field (ok) that TypeScript uses to narrow to the correct variant:
type Result<T, E = string> =
| { ok: true; value: T } // success branch
| { ok: false; error: E } // failure branch
function divide(a: number, b: number): Result<number, string> {
if (b === 0) return err('Division by zero');
return ok(a / b);
}
const result = divide(10, 0);
if (result.ok) {
console.log(result.value); // TypeScript: number ✅
} else {
console.log(result.error); // TypeScript: string ✅
}| Function | Signature | Description |
|---|---|---|
ok(value) | <T>(v: T) → Ok<T> | Wraps a successful value |
err(error) | <E>(e: E) → Err<E> | Wraps an error |
unwrapOr(result, default) | <T,E>(r: Result<T,E>, d: T) → T | Returns value or default |
isOk(result) | <T,E>(r: Result<T,E>) → r is Ok<T> | Type guard for success |
The isOk return type result is Ok<T> is a type guard — calling it narrows result to the success branch.
Sample tests