interface ResultInterface { unwrap: () => T | E; readonly success: boolean; } export class ResultSuccess implements ResultInterface { data: T; readonly success = true; constructor(data: T) { this.data = data; } unwrap(): T { return this.data; } } export class ResultError implements ResultInterface { error: E; readonly success = false; constructor(error: E) { this.error = error; } unwrap(): E { return this.error; } } export type Result = ResultSuccess | ResultError; export function ok(value?: T): ResultSuccess; export function ok(value: T) { return new ResultSuccess(value); } export function fail(error?: T): ResultError; export function fail(error: T) { return new ResultError(error); } export function fromPromise( promise: Promise, ): Promise> { return promise.then(ok).catch(fail); } export function catchThrow(func: () => T): Result { try { return ok(func()); } catch (error) { return fail(error); } }