/** * A successful value */ export type Ok = { _tag: 'ok'; value: R }; /** * A failed value */ export type Err = { _tag: 'error'; error: L }; /** * A safe result type: imagine a language with no exceptions — the way to handle * errors would be to use something like a tagged union type. * * Why would we want that? I want to explicitly handle exceptions in this library * and having this construct really helps. It's also pretty easy to implement. */ export type Result = Err | Ok; export function ok(value: O): Ok { return { _tag: 'ok', value }; } export function err(error: E): Err { return { _tag: 'error', error }; } /** * Checks whether a value is an `Ok`. * Handy with TypeScript guards */ export function isOk(result: Result): result is Ok { return result._tag === 'ok'; } /** * Checks whether a value is an `Err`. * Handy with TypeScript guards */ export function isErr(either: Result): either is Err { return either._tag === 'error'; } /** * Convert a `Promise` into a `Promise>`, * therefore catching the errors and being able to handle them explicitly */ export async function safeAsync( promise: Promise ): Promise> { try { const value = await promise; return ok(value); } catch (e) { return err(e); } }