@stencil/core
Version:
A Compiler for Web Components and Progressive Web Apps
113 lines (112 loc) • 3.64 kB
TypeScript
/**
* A Result wraps up a success state and a failure state, allowing you to
* return a single type from a function and discriminate between the two
* possible states in a principled way.
*
* Using it could look something like this:
*
* ```ts
* import { result } from '@utils';
*
* const mightFail = (input: number): Result<number, string> => {
* try {
* let value: number = calculateSomethingWithInput(input);
* return result.ok(value);
* } catch (e) {
* return result.err(e.message);
* }
* }
*
* const sumResult = mightFail(2);
*
* const msg = result.map(sumResult, (sum: number) => `the sum was: ${sum}`);
* ```
*
* A few utility methods are defined in this module, like `map` and `unwrap`,
* which are (probably obviously) inspired by the correspond methods on
* `std::result::Result` in Rust.
*/
export type Result<OnSuccess, OnFailure> = Ok<OnSuccess> | Err<OnFailure>;
/**
* Type for the Ok state of a Result
*/
type Ok<T> = {
isOk: true;
isErr: false;
value: T;
};
/**
* Type for the Err state of a Result
*/
type Err<T> = {
isOk: false;
isErr: true;
value: T;
};
/**
* Create an `Ok` given a value. This doesn't do any checking that the value is
* 'ok-ish' since doing so would make an undue assumption about what is 'ok'.
* Instead, this trusts the user to determine, at the call site, whether
* something is `ok()` or `err()`.
*
* @param value the value to wrap up in an `Ok`
* @returns an Ok wrapping the value
*/
export declare const ok: <T>(value: T) => Ok<T>;
/**
* Create an `Err` given a value.
*
* @param value the value to wrap up in an `Err`
* @returns an Ok wrapping the value
*/
export declare const err: <T>(value: T) => Err<T>;
/**
* Map across a `Result`.
*
* If it's `Ok`, unwraps the value, applies the supplied function, and returns
* the result, wrapped in `Ok` again. This could involve changing the type of
* the wrapped value, for instance:
*
* ```ts
* import { result } from "@utils";
*
* const myResult: Result<string, string> = result.ok("monads???");
* const updatedResult = result.map(myResult, wrappedString => (
* wrappedString.split("").length
* ));
* ```
*
* after the `result.map` call the type of `updatedResult` will now be
* `Result<number, string>`.
*
* If it's `Err`, just return the same value.
*
* This lets the programmer trigger an action, or transform a value, only if an
* earlier operation succeeded, short-circuiting instead if an error occurred.
*
* @param result a `Result` value which we want to map across
* @param fn a function for handling the `Ok` case for the `Result`
* @returns a new `Result`, with the a new wrapped value (if `Ok`) or the
* same (if `Err)
*/
export declare function map<T1, T2, E>(result: Result<T1, E>, fn: (t: T1) => Promise<T2>): Promise<Result<T2, E>>;
export declare function map<T1, T2, E>(result: Result<T1, E>, fn: (t: T1) => T2): Result<T2, E>;
/**
* Unwrap a {@link Result}, return the value inside if it is an `Ok` and
* throw with the wrapped value if it is an `Err`.
*
* @throws with the wrapped value if it is an `Err`.
* @param result a result to peer inside of
* @returns the wrapped value, if `Ok`
*/
export declare const unwrap: <T, E>(result: Result<T, E>) => T;
/**
* Unwrap a {@link Result}, return the value inside if it is an `Err` and
* throw with the wrapped value if it is an `Ok`.
*
* @throws with the wrapped value if it is an `Ok`.
* @param result a result to peer inside of
* @returns the wrapped value, if `Err`
*/
export declare const unwrapErr: <T, E>(result: Result<T, E>) => E;
export {};