Skip to content

Instantly share code, notes, and snippets.

@cshaa
Created June 17, 2025 13:09
Show Gist options
  • Save cshaa/34cddad8e1747db4068b43ebb970bd50 to your computer and use it in GitHub Desktop.
Save cshaa/34cddad8e1747db4068b43ebb970bd50 to your computer and use it in GitHub Desktop.
class ResultClass<IsOk extends boolean, OkType, ErrType> {
constructor(
/**
* For `Ok(value)` returns `true`; for `Err(value)` returns `false`.
*/
public readonly isOk: IsOk,
/**
* For `Ok(value)` returns `value`; for `Err(value)` returns `undefined`.
*/
public readonly okInner: IsOk extends true ? OkType : undefined,
/**
* For `Ok(value)` returns `undefined`; for `Err(value)` returns `value`.
*/
public readonly errInner: IsOk extends true ? undefined : ErrType
) {}
*[Symbol.iterator](): IterableIterator<OkType> {
if (this.isOk) yield this.okInner!;
}
get isErr(): IsOk extends true ? false : IsOk extends false ? true : boolean {
return !this.isOk as any;
}
isOkAnd(fn: (x: OkType) => boolean): boolean {
if (this.isOk) return fn(this.okInner!);
return false;
}
isErrAnd(fn: (e: ErrType) => boolean): boolean {
if (this.isErr) return fn(this.errInner!);
return false;
}
map<S>(fn: (value: OkType) => S): Result<S, ErrType> {
if (this.isOk) return Result.Ok(fn(this.okInner!));
return self as any;
}
mapErr<E>(fn: (err: ErrType) => E): Result<OkType, E> {
if (this.isErr) return Result.Err(fn(this.errInner!));
return self as any;
}
}
type Result<T, E> = Result.Ok<T> | Result.Err<E>;
namespace Result {
export type Ok<T> = ResultClass<true, T, never>;
export const Ok = <T>(value: T) => new ResultClass(true, value, undefined as never);
export type Err<E> = ResultClass<false, never, E>;
export const Err = <E>(err: E) => new ResultClass(false, undefined as never, err);
export function from<T>(fn: () => T): Result<T, any>;
export function from<T>(fn: Promise<T>): Promise<Result<T, any>>;
export function from<T>(fn: Promise<T> | (() => T)): Result<T, any> | Promise<Result<T, any>> {
if (typeof fn === 'function') {
try {
return Result.Ok(fn());
} catch (e) {
return Result.Err(e);
}
} else {
return (async () => {
try {
return Result.Ok(await fn);
} catch (e) {
return Result.Err(e);
}
})();
}
}
}
export { Result };
export const isResult = (x: unknown): x is Result<unknown, unknown> => x instanceof ResultClass;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment