Type-safe error handling for TypeScript. No more try/catch blocks.
npm install @itsezz/try-catchtype Result<T, E = Error> = Success<T> | Failure<E>;
type Success<T> = { data: T; error?: never; ok: true };
type Failure<E> = { data?: never; error: E; ok: false };Use result.ok to check success/failure with full TypeScript narrowing.
import { tryCatch, isError } from '@itsezz/try-catch';
// Sync
const result = tryCatch(() => JSON.parse('{"name":"user"}'));
if (result.ok) console.log(result.data.name); // "user"
else console.error(result.error);
// Async
const user = await tryCatch(fetch('/api/user').then(r => r.json()));
if (isError(user)) return null;
return user.data;| Function | Short alias | Returns | Description |
|---|---|---|---|
tryCatch() |
t() |
Result | Promise<Result> |
Auto-detects sync/async |
tryCatchSync() |
tc() |
Result |
Guaranteed sync |
tryCatchAsync() |
tca() |
Promise<Result> |
Guaranteed async |
Note:
tryCatchmay not correctly infer if the result isPromise<Result<T,E>>orResult<T,E>in certain conditions and defaults toPromise<Result<T,E>>when unsure. Use explicit variants for guaranteed type safety.
success(42) // { data: 42, ok: true }
failure('err') // { error: 'err', ok: false }if (result.ok) result.data; // Success<T>
else result.error; // Failure<E>
isSuccess(result); // type guard
isError(result); // type guardmap(result, fn) // transform success value
flatMap(result, fn) // chain operations returning Result
unwrapOr(result, default) // get value or default
unwrapOrElse(result, fn) // get value or compute from error
match(result, { // pattern matching
success: (data) => ...,
failure: (error) => ...
})const json = tryCatch(() => JSON.parse(input));
if (!json.ok) return { error: 'Invalid JSON' };
return json.data;interface User {
id: number;
name: string;
}
const fetchUser = async (): Promise<User | null> => {
const result = await tryCatch(fetch('/api/user').then(r => r.json()));
if (result.ok) return result.data;
return null;
};const validate = (input: unknown): Result<User, string[]> => {
const parsed = tryCatch(() => JSON.parse(input as string));
if (!parsed.ok) return failure(['Invalid JSON']);
const errors: string[] = [];
if (!parsed.data.name) errors.push('Name required');
return errors.length > 0 ? failure(errors) : success(parsed.data);
};const result = unwrapOr(
flatMap(success('42'), s => success(parseInt(s))),
0
); // 84Default error type? Error. Use generics for custom types:
tryCatch<number, ApiError>(() => fetchData())When to use each variant?
tryCatch: Don't care about sync/async distinctiontryCatchSync: Need guaranteed sync returntryCatchAsync: Need guaranteedPromise<Result>return
MIT