export type Result = Ok | Err; class Ok { readonly value: T; constructor(value: T) { this.value = value; } isOk(): this is Ok { return true; } isErr(): this is Err { return false; } map(fn: (val: T) => U): Result { return new Ok(fn(this.value)); } mapErr(_fn: (err: E) => F): Result { return new Ok(this.value); } unwrap(): T { return this.value; } unwrapOr(_default: T): T { return this.value; } match(handlers: { ok: (val: T) => U, err: (err: E) => U }): U { return handlers.ok(this.value); } andThen(fn: (val: T) => Result): Result { return fn(this.value); } } class Err { readonly error: E; constructor(error: E) { this.error = error; } isOk(): this is Ok { return false; } isErr(): this is Err { return true; } map(_fn: (val: T) => U): Result { return new Err(this.error); } mapErr(fn: (err: E) => F): Result { return new Err(fn(this.error)); } unwrap(): T { throw new Error('Tried to unwrap Err: ' + this.error); } unwrapOr(defaultValue: T): T { return defaultValue; } match(handlers: { ok: (val: T) => U, err: (err: E) => U }): U { return handlers.err(this.error); } andThen(_fn: (val: T) => Result): Result { return new Err(this.error); } } export function ok(value: T): Result { return new Ok(value); } export function err(error: E): Result { return new Err(error); }