Rust-inspired Result type for type-safe error handling without try/catch
npm install @philiprehberger/resultRust-inspired Result type for type-safe error handling without try/catch
npm install @philiprehberger/result
import { ok, err, tryCatch, tryCatchAsync } from '@philiprehberger/result';
const success = ok(42);
const failure = err(new Error('something broke'));
// Wrap throwing functions
const result = tryCatch(() => JSON.parse(input));
// Result<unknown, Error>
// Wrap async functions
const apiResult = await tryCatchAsync(() => fetch('/api/data'));
// Result<Response, Error>
result.unwrap(); // returns value or throws
result.unwrapOr('default'); // returns value or default
result.unwrapErr(); // returns error or throws
result.match({
ok: (value) => `Got: ${value}`,
err: (error) => `Error: ${error.message}`,
});
const name = tryCatch(() => JSON.parse(input))
.map(data => data.name)
.map(name => name.toUpperCase())
.unwrapOr('UNKNOWN');
const result = err('not found')
.orElse(e => ok('fallback value'));
// Ok('fallback value')
tryCatch(() => JSON.parse(input))
.tap(data => console.log('Parsed:', data))
.tapErr(err => console.error('Parse failed:', err))
.map(data => data.name);
if (result.isOk()) {
result.value; // typed as T
}
if (result.isErr()) {
result.error; // typed as E
}
import { all, combine, partition } from '@philiprehberger/result';
const results = all([ok(1), ok(2), ok(3)]);
// Ok([1, 2, 3])
const withError = all([ok(1), err('fail'), ok(3)]);
// Err('fail') — returns first error
// combine is an alias of all
combine([ok(1), ok(2)]);
// partition keeps every result and splits oks from errs
const { oks, errs } = partition([ok(1), err('a'), ok(2)]);
// oks = [1, 2], errs = ['a']
import { fromPromise } from '@philiprehberger/result';
const result = await fromPromise(fetch('/api'));
// Result<Response, Error>
const result = ok(42);
await result.toPromise(); // resolves to 42
const failure = err(new Error('fail'));
await failure.toPromise(); // rejects with Error
const result = ok(42).filter(
(n) => n > 0,
() => new Error('must be positive'),
);
// Ok(42)
ok(-1).filter(
(n) => n > 0,
() => new Error('must be positive'),
);
// Err('must be positive')
import { flatten } from '@philiprehberger/result';
const nested = ok(ok(42)); // Result<Result<number, Error>, Error>
const flat = flatten(nested); // Ok(42)
const result = tryCatch(
() => JSON.parse(input),
(e) => ({ code: 'PARSE_ERROR', cause: e }),
);
// Result<unknown, { code: string; cause: unknown }>
const asyncResult = await tryCatchAsync(
() => fetch('/api'),
(e) => new MyCustomError(e),
);
| Function | Returns | Description |
|---|---|---|
ok(value) | Ok<T> | Create a success result |
err(error) | Err<E> | Create a failure result |
tryCatch(fn, mapError?) | Result<T, E> | Wrap a throwing function |
tryCatchAsync(fn, mapError?) | Promise<Result<T, E>> | Wrap an async throwing function |
fromPromise(promise) | Promise<Result<T, Error>> | Convert a promise to a Result |
all(results) | Result<T[], E> | Collect an array of Results; returns first error |
combine(results) | Result<T[], E> | Alias of all |
partition(results) | { oks, errs } | Split a list of Results into success and failure values |
flatten(result) | Result<T, E> | Unwrap a nested Result<Result<T, E>, E> |
| Method | Returns | Description |
|---|---|---|
isOk() | boolean | Type guard for Ok |
isErr() | boolean | Type guard for Err |
map(fn) | Result<U, E> | Transform the success value |
mapErr(fn) | Result<T, F> | Transform the error value |
flatMap(fn) | Result<U, E> | Chain with a Result-returning function |
unwrap() | T | Extract value or throw |
unwrapOr(default) | T | Extract value or return default |
unwrapErr() | E | Extract error or throw |
orElse(fn) | Result<T, F> | Recover from an error |
tap(fn) | this | Side effect on success value |
tapErr(fn) | this | Side effect on error value |
match({ ok, err }) | U | Pattern match on Ok/Err |
toPromise() | Promise<T> | Convert to a Promise |
filter(predicate, errorFactory) | Result<T, E> | Keep Ok if predicate passes, else Err |
mapAsync(fn) | Promise<Result<U, E>> | Async version of map |
flatMapAsync(fn) | Promise<Result<U, E>> | Async version of flatMap |
npm install
npm run build
npm test
If you find this project useful: