Creating Results
Create Ok and Err values and safely capture synchronous or asynchronous exceptions.
Result.ok
const count = Result.ok(3); // Ok<number, never>
const done = Result.ok(); // Ok<void, never>
An Ok stores its payload in .value and has status: "ok".
Result.err
const missing = Result.err(new UserNotFound({ id }));
// Err<never, UserNotFound>
An Err stores its payload in .error and has status: "error". Prefer meaningful error objects over strings at module boundaries.
Result.try
Capture a synchronous throwing API:
const parsed = Result.try(() => JSON.parse(input));
// Result<unknown, UnhandledException>
Without a custom catch, the original thrown value is available as UnhandledException.cause.
Map the exception into your domain:
class InvalidJson extends TaggedError("InvalidJson")<{
cause: unknown;
message: string;
}> {}
const parsed = Result.try({
try: () => JSON.parse(input),
catch: (cause) => new InvalidJson({ cause, message: "Input is not valid JSON" }),
});
// Result<unknown, InvalidJson>
The callback receives { attempt }. Synchronous retry runs immediately and is bounded by times:
const value = Result.try(({ attempt }) => readFlakyValue(attempt), {
retry: { times: 2 }, // one initial attempt, at most two retries
});
Result.tryPromise
Capture a Promise-returning operation:
const response = await Result.tryPromise(() => fetch(url));
// Result<Response, UnhandledException>
Use an object to create a typed error:
const response = await Result.tryPromise({
try: () => fetch(url),
catch: (cause) => new NetworkError({ cause, url, message: "Request failed" }),
});
Retries, delays, backoff, jitter, and cancellation are covered in Async operations and retries.