Skip to content

Instantly share code, notes, and snippets.

@janwirth
Last active January 6, 2020 06:22
Show Gist options
  • Save janwirth/ea837d71ea3be1da830abecfc7bd37f9 to your computer and use it in GitHub Desktop.
Save janwirth/ea837d71ea3be1da830abecfc7bd37f9 to your computer and use it in GitHub Desktop.
JS Result Data Type with Typescript Typings
/**
* An either type with more specific semantics
*/
type Result<O, E> = Ok<O> | Err<E>;
interface Ok<O> {
type: "Ok";
value: O;
}
interface Err<E> {
type: "Err";
err: E;
}
declare function ok(value: O): Result<O, E>;
declare function err(value: O): Result<O, E>;
declare function match<E, D, R>(
matchers: ResultMatchers<E, D, R>
): (remoteData: Result<E, D>) => R;
declare function map<E, D>(
fn: (D) => D_
): (remoteData: Result<E, D>) => Result<E, D_>;
declare function isOk(result: Result<any, any>): boolean;
declare function isErr(result: Result<any, any>): boolean;
// Example: ResultMatchers<HttpError, VehicleList>
export interface ResultMatchers<E, D, R> {
Err: (E) => R;
Ok: (D) => R;
}
export const ok = value => ({ type: "Ok", value });
export const err = err => ({ type: "Err", err });
export const map = fn => res => (res.type == "Ok" ? ok(fn(res.value)) : res);
/**
* This function takes an object with a property of each state that remote data can be in.
* The corresping function will be called depending on what type of remmote data we pass in.
*/
export const match = matchers => remoteData => {
switch (remoteData.type) {
case "Err":
return matchers.Failure(remoteData.err);
case "Ok":
return matchers.Success(remoteData.value);
}
};
export const isOk = remoteData => remoteData.type == "Ok";
export const isErr = remoteData => remoteData.type == "Err";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment