export type Result = | { ok: true; value: T } | { ok: false; error: E }; export default class Result2 { /** True if this is an Ok variant, False if this is an Err variant */ #ok: boolean; /** Always present for Ok values, otherwise undefined */ #value?: T; /** Always present for Err values, otherwise undefined */ #error?: E; private constructor(ok: boolean, value: T, error: E) { this.#ok = ok; this.#value = value; this.#error = error; } static Ok(value: T): Result2 { return new Result2(true, value, undefined as E); } static Err(error: E): Result2 { return new Result2(false, undefined as T, error); } ok(): T | undefined { return this.#ok ? this.#value : undefined; } err(): E | undefined { return this.#ok ? undefined : this.#error; } unwrap(): T { if (this.#ok) { return this.#value!; } else { throw this.#error; } } or(value: T): Result2 { if (this.#ok) return this; else return Result2.Ok(value); } } export const ok = (value: T): Result => ({ ok: true, value }); export const err = (error: E): Result => ({ ok: false, error }); /** Unwrap an OK value or throw an exception */ export const unwrap = (result: Result): T => { if (!result.ok) throw result.error; return result.value; };