export interface Result { isOk(): this is Ok; isErr(): this is Err; map(fn: (value: T) => U): Result; unwrap(): T | never; unwrapOrDefault(defaultValue: T): T; } export function ok(): Result; export function ok(value: T): Result; export function ok(value?: T): Result { return new Ok(value as T); } export function err(): Result; export function err(error: E): Result; export function err(error?: E): Result { return new Err(error as E); } export class Ok implements Result { constructor(public value: T) {} isOk(): this is Ok { return true; } isErr(): this is Err { return false; } map(fn: (value: T) => U): Result { return new Ok(fn(this.value)); } unwrap(): T { return this.value; } unwrapOrDefault(_defaultValue: T): T { return this.value; } } export class Err implements Result { constructor(public error: E) {} isOk(): this is Ok { return false; } isErr(): this is Err { return true; } map(_fn: (value: T) => U): Result { return new Err(this.error); } unwrap(): T { throw new Error(`Called unwrap on Err: ${this.error}`); } unwrapOrDefault(defaultValue: T): T { return defaultValue; } }