type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
function ok<T>(value: T): Result<T, never> {
return { ok: true, value };
}
function err<E>(error: E): Result<never, E> {
return { ok: false, error };
}
async function safeAsync<T>(promise: Promise<T>): Promise<Result<T, Error>> {
try {
const value = await promise;
return ok(value);
} catch (error) {
return err(error instanceof Error ? error : new Error(String(error)));
}
}Usage
async function fetchUser(id: number): Promise<Result<User, string>> {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
return err(`Failed to fetch user: ${response.status}`);
}
const user = await response.json();
return ok(user);
}
// No try-catch needed
const result = await fetchUser(1);
if (result.ok) {
console.log(result.value.name); // Type-safe access
} else {
console.error(result.error); // Error handling
}