Skip to content

Instantly share code, notes, and snippets.

@aleics
Created February 4, 2021 17:51
Show Gist options
  • Save aleics/0a7d09cc00156584b4ac7641b0f1a266 to your computer and use it in GitHub Desktop.
Save aleics/0a7d09cc00156584b4ac7641b0f1a266 to your computer and use it in GitHub Desktop.
Rust Result in Typescript 🦀
interface Cases<O, T, E, R> {
ok: (value: O) => T;
err: (value: E) => R;
}
export abstract class Result<O, E> {
public abstract isOk(): boolean;
public abstract isErr(): boolean;
public abstract match<T, R>(cases: Cases<O, T, E, R>): T | R;
public abstract map<T>(fn: (value: O) => T): Result<T, E>;
public abstract mapErr<T>(fn: (value: E) => T): Result<O, T>;
public abstract and<T>(result: Result<T, E>): Result<T, E>;
public abstract andThen<T>(fn: (value: O) => Result<T, E>): Result<T, E>;
public abstract or<R>(result: Result<O, R>): Result<O, R>;
public abstract orElse<R>(fn: (value: E) => Result<O, R>): Result<O, R>;
}
class OkResult<O, E> extends Result<O, E> {
private value: O;
private constructor(value: O) {
super();
this.value = value;
}
static of<O, E>(value: O): OkResult<O, E> {
return new OkResult(value);
}
isOk(): boolean {
return true;
}
isErr(): boolean {
return false;
}
match<T, R>(cases: Cases<O, T, E, R>): T {
return cases.ok(this.value);
}
map<T>(fn: (value: O) => T): Result<T, E> {
return OkResult.of(fn(this.value));
}
mapErr<T>(_fn: (value: E) => T): Result<O, T> {
return OkResult.of(this.value);
}
and<T>(result: Result<T, E>): Result<T, E> {
return result;
}
andThen<T>(fn: (value: O) => Result<T, E>): Result<T, E> {
return fn(this.value);
}
or<R>(_result: Result<O, R>): Result<O, R> {
return OkResult.of(this.value);
}
orElse<R>(_fn: (value: E) => Result<O, R>): Result<O, R> {
return OkResult.of(this.value);
}
}
class ErrResult<O, E> extends Result<O, E> {
private value: E;
private constructor(value: E) {
super();
this.value = value;
}
static of<O, E>(value: E): ErrResult<O, E> {
return new ErrResult(value);
}
isOk(): boolean {
return false;
}
isErr(): boolean {
return true;
}
match<T, R>(cases: Cases<O, T, E, R>): R {
return cases.err(this.value);
}
map<T>(_fn: (value: O) => T): Result<T, E> {
return ErrResult.of(this.value);
}
mapErr<T>(fn: (value: E) => T): Result<O, T> {
return ErrResult.of(fn(this.value));
}
and<T>(_result: Result<T, E>): Result<T, E> {
return ErrResult.of(this.value);
}
andThen<T>(_fn: (value: O) => Result<T, E>): Result<T, E> {
return ErrResult.of(this.value);
}
or<R>(result: Result<O, R>): Result<O, R> {
return result;
}
orElse<R>(fn: (value: E) => Result<O, R>): Result<O, R> {
return fn(this.value);
}
}
export function Err<O, E>(value: E): Result<O, E> {
return ErrResult.of(value);
}
export function Ok<O, E>(value: O): Result<O, E> {
return OkResult.of(value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment