Options
All
  • Public
  • Public/Protected
  • All
Menu

External module "result"

Result

A Result<T, E> is a type representing the value result of an operation which may fail, with a successful value of type T or an error of type E.

If the value is present, it is Ok(value). If it's absent, it's Err(reason). This provides a type-safe container for dealing with the possibility that an error occurred, without needing to scatter try/catch blocks throughout your codebase. This has two major advantages:

  1. You know when an item may have a failure case, unlike exceptions (which may be thrown from any function with no warning and no help from the type system).
  2. The error scenario is a first-class citizen, and the provided helper functions and methods allow you to deal with the type in much the same way as you might an array – transforming values if present, or dealing with errors instead if necessary.

Having the possibility of an error handed to you as part of the type of an item gives you the flexibility to do the same kinds of things with it that you might with any other nice container type. For example, you can use map to apply a transformation if the item represents a successful outcome, and even if the result was actually an error, it won't break under you.

To make that concrete, let's look at an example. In normal JavaScript, you might have something like this:

function mightSucceed(doesSucceed) {
  if (!doesSucceed) {
    throw new Error('something went wrong!');
  }

  return 42;
}

const doubleTheAnswer = mightSucceed(true) * 2;
console.log(doubleTheAnswer); // 84; this is fine

const doubleAnError = mightSucceed(false) * 2; // throws an uncaught exception
console.log(doubleAnErr); // never even gets here because of the exception

If we wanted to handle that error, we'd need to first of all know that the function could throw an error. Assuming we knew that – probably we'd figure it out via painful discovery at runtime, or by documenting it in our JSDoc – then we'd need to wrap it up in a try/catch block:

try {
  const doubleTheAnswer = mightSucceed(true) * 2;
  console.log(doubleTheAnswer);

  const doubleAnError = mightSucceed(false) * 2;
} catch (ex) {
  console.log(ex.message);
}

This is a pain to work with!

The next thing we might try is returning an error code and mutating an object passed in. (This is the standard pattern for non-exception-based error handling in C, C++, Java, and C#, for example.) But that has a few problems:

  • You have to mutate an object. This doesn't work for simple items like numbers, and it can also be pretty unexpected behavior at times – you want to know when something is going to change, and mutating freely throughout a library or application makes that impossible.

  • You have to make sure to actually check the return code to make sure it's valid. In theory, we're all disciplined enough to always do that. In practice, we often end up reasoning, Well, this particular call can never fail... (but of course, it probably can, just not in a way we expect).

  • We don't have a good way to return a reason for the error. We end up needing to introduce another parameter, designed to be mutated, to make sure that's possible.

  • Even if you go to all the trouble of doing all of that, you need to make sure – every time – that you use only the error value if the return code specified an error, and only the success value if the return code specified that it succeeded.

(Note that in slightly varied form, this is also basically what the Node.js callback pattern gives you. It's just a conventional way of needing to check for an error on every callback invocation, since you don't actually have a return code in that case.)

Our way out is Result. It lets us just return one thing from a function, which encapsulates the possibility of failure in the very thing we return. We get:

  • the simplicity of just dealing with the return value of a function (no try/catch to worry about!)
  • the ease of expressing an error we got with throwing an exception
  • the explicitness about success or failure that we got with a return code

Here's what that same example from above would look like using Result:

import Result, { ok, err, map, toString } from 'true-myth/result';

function mightSucceed(doesSucceed: boolean): Result<number, string> {
  return doesSucceed ? ok(42) : err('something went wrong!');
}

const double = (x: number) => x * 2;

const doubleTheAnswer = map(double, mightSucceed(true));
console.log(toString(doubleTheAnswer)); // `Ok(84)`

const doubleAnErr = map(double, mightSucceed(false));
console.log(toString(doubleAnErr)); // `Err('something went wrong')`

Note that if we tried to call mightSucceed(true) * 2 here, we'd get a type error – this wouldn't make it past the compile step. Instead, we need to use one of the helper functions (or methods) to manipulate the value in a safe way.

Using Result

The library is designed to be used with a functional style, allowing you to compose operations easily. Thus, standalone pure function versions of every operation are supplied. However, the same operations also exist on the Ok and Err types directly, so you may also write them in a more traditional "fluent" object style.

Examples: functional style

import { ok, err, map, toString } from 'true-myth/result';

const length = (s: string) => s.length;

const anOk = ok('some string');
const okLength = map(length, anOk);
console.log(toString(okLength)); // Ok(11)

const anErr = err('gah!');
const errLength = map(length, anErr);
console.log(toString(errLength)); // Err(gah!)

Examples: fluent object invocation

You can also use a "fluent" method chaining style to apply the various helper functions to a Result instance:

import { ok, err } from 'true-myth/result';

const length = (s: string) => s.length;

const hooray = ok('yay');
const okLen = hooray.map(length).unwrapOr(0); // okLen = 3

const muySad = err('oh no');
const errLen = muySad.map(length).unwrapOr(0); // errLen = 0

Writing type constraints

When creating a Result instance, you'll nearly always be using either the Ok or the Err type, so the type system won't necessarily be able to infer the other type parameter.

import { ok, err } from 'true-myth/result';

const anOk = ok(12); // TypeScript infers: `Result<number, {}>`
const anErr = err('sad'); // TypeScript infers: `Result<{}, string>`

In TypeScript, because of the direction type inference happens, you will need to specify the type at declaration to make it type check when returning values from a function with a specified type. Note that this only applies when the instance is declared in its own statement and returned separately, not when it is the expression value of a single-expression arrow function or the explicit return value of any function.

import Result, { ok } from 'true-myth/result';

// ERROR: Type 'Result<number, {}>' is not assignable to type 'Result<number, string>'.
const getAResultNotAssignable = (): Result<number, string> => {
  const theResult = ok(12);
  return theResult;
};

// Succeeds
const getAResultExpression = (): Result<number, string> => ok(12);

// Succeeds
const getAResultReturn = (): Result<number, string> => {
  return ok(12);
};

Index

Type aliases

Matcher

Matcher<T, E, A>: object

A lightweight object defining how to handle each variant of a Maybe.

Type parameters

  • T

  • E

  • A

Type declaration

  • Err: function
      • (error: E): A
      • Parameters

        • error: E

        Returns A

  • Ok: function
      • (value: T): A
      • Parameters

        • value: T

        Returns A

Maybe

Maybe<T>: Just<T> | Nothing<T>

Type parameters

  • T

Result

Result<T, E>: Ok<T, E> | Err<T, E>

A value which may (Ok) or may not (Err) be present.

The behavior of this type is checked by TypeScript at compile time, and bears no runtime overhead other than the very small cost of the container object.

Type parameters

  • T

  • E

ResultJSON

ResultJSON<T, E>: OkJSON<T> | ErrJSON<E>

Type parameters

  • T

  • E

Variables

Const cata

cata: match = match

Alias for match

Const chain

chain: andThen = andThen

Alias for andThen.

Const flatMap

flatMap: andThen = andThen

Alias for andThen.

Const getOr

getOr: unwrapOr = unwrapOr

Alias for unwrapOr

Const getOrElse

getOrElse: unwrapOrElse = unwrapOrElse

Alias for unwrapOrElse

Const of

of: ok = ok

Result.of is an alias for Result.ok.

Const unsafeGet

unsafeGet: unsafelyUnwrap = unsafelyUnwrap

Alias for unsafelyUnwrap

Const unsafelyGet

unsafelyGet: unsafelyUnwrap = unsafelyUnwrap

Alias for unsafelyUnwrap

Const unsafelyGetErr

unsafelyGetErr: unsafelyUnwrapErr = unsafelyUnwrapErr

Alias for unsafelyUnwrapErr

Functions

and

  • and<T, U, E>(andResult: Result<U, E>, result: Result<T, E>): Result<U, E>
  • and<T, U, E>(andResult: Result<U, E>): function
  • You can think of this like a short-circuiting logical "and" operation on a Result type. If result is Ok, then the result is the andResult. If result is Err, the result is the Err.

    This is useful when you have another Result value you want to provide if and only if you have an Ok – that is, when you need to make sure that if you Err, whatever else you're handing a Result to also gets that Err.

    Notice that, unlike in map or its variants, the original result is not involved in constructing the new Result.

    Examples

    import { and, ok, err, toString } from 'true-myth/result';
    
    const okA = ok('A');
    const okB = ok('B');
    const anErr = err({ so: 'bad' });
    
    console.log(toString(and(okB, okA)));  // Ok(B)
    console.log(toString(and(okB, anErr)));  // Err([object Object])
    console.log(toString(and(anErr, okA)));  // Err([object Object])
    console.log(toString(and(anErr, anErr)));  // Err([object Object])

    Type parameters

    • T

      The type of the value wrapped in the Ok of the Result.

    • U

      The type of the value wrapped in the Ok of the andResult, i.e. the success type of the Result present if the checked Result is Ok.

    • E

      The type of the value wrapped in the Err of the Result.

    Parameters

    • andResult: Result<U, E>

      The Result instance to return if result is Err.

    • result: Result<T, E>

      The Result instance to check.

    Returns Result<U, E>

  • Type parameters

    • T

    • U

    • E

    Parameters

    Returns function

andThen

  • andThen<T, U, E>(thenFn: function, result: Result<T, E>): Result<U, E>
  • andThen<T, U, E>(thenFn: function): function
  • Apply a function to the wrapped value if Ok and return a new Ok containing the resulting value; or if it is Err return it unmodified.

    This differs from map in that thenFn returns another Result. You can use andThen to combine two functions which both create a Result from an unwrapped type.

    You may find the .then method on an ES6 Promise helpful for comparison: if you have a Promise, you can pass its then method a callback which returns another Promise, and the result will not be a nested promise, but a single Promise. The difference is that Promise#then unwraps all layers to only ever return a single Promise value, whereas Result.andThen will not unwrap nested Results.

    This is also commonly known as (and therefore aliased as) flatMap or chain. It is sometimes also known as bind, but not aliased as such because bind already means something in JavaScript.

    Examples

    import { ok, err, andThen, toString } from 'true-myth/result';
    
    const toLengthAsResult = (s: string) => ok(s.length);
    
    const anOk = ok('just a string');
    const lengthAsResult = andThen(toLengthAsResult, anOk);
    console.log(toString(lengthAsResult));  // Ok(13)
    
    const anErr = err(['srsly', 'whatever']);
    const notLengthAsResult = andThen(toLengthAsResult, anErr);
    console.log(toString(notLengthAsResult));  // Err(srsly,whatever)

    Type parameters

    • T

      The type of the value wrapped in the Ok of the Result.

    • U

      The type of the value wrapped in the Ok of the Result returned by the thenFn.

    • E

      The type of the value wrapped in the Err of the Result.

    Parameters

    • thenFn: function

      The function to apply to the wrapped T if maybe is Just.

    • result: Result<T, E>

      The Maybe to evaluate and possibly apply a function to.

    Returns Result<U, E>

  • Type parameters

    • T

    • U

    • E

    Parameters

    • thenFn: function

    Returns function

ap

  • ap<T, U, E>(resultFn: Result<function, E>, result: Result<T, E>): Result<U, E>
  • ap<T, U, E>(resultFn: Result<function, E>): function
  • Allows you to apply (thus ap) a value to a function without having to take either out of the context of their Results. This does mean that the transforming function is itself within a Result, which can be hard to grok at first but lets you do some very elegant things. For example, ap allows you to do this:

    import Result from 'true-myth/result';
    
    const one = Result.ok<number, string>(1);
    const five = Result.ok<number, string>(5);
    const whoops = Result.err<number, string>('oh no');
    
    const add = (a: number) => (b: number) => a + b;
    const resultAdd = Result.ok<typeof add, string>(add);
    
    resultAdd.ap(one).ap(five); // Ok(6)
    resultAdd.ap(one).ap(whoops); // Err('oh no')
    resultAdd.ap(whoops).ap(five) // Err('oh no')

    Without Result.ap, you'd need to do something like a nested Result.match:

    import { ok, err } from 'true-myth/result';
    
    const one = ok<number, string>(1);
    const five = ok<number, string>(5);
    const whoops = err<number, string>('oh no');
    
    one.match({
    Ok: n => five.match({
    Ok: o => ok<number, string>(n + o),
    Err: e => err<number, string>(e),
    }),
    Err: e  => err<number, string>(e),
    }); // Ok(6)
    
    one.match({
    Ok: n => whoops.match({
    Ok: o => ok<number, string>(n + o),
    Err: e => err<number, string>(e),
    }),
    Err: e  => err<number, string>(e),
    }); // Err('oh no')
    
    whoops.match({
    Ok: n => five.match({
    Ok: o => ok(n + o),
    Err: e => err(e),
    }),
    Err: e  => err(e),
    }); // Err('oh no')

    And this kind of thing comes up quite often once you're using Maybe to handle optionality throughout your application.

    For another example, imagine you need to compare the equality of two ImmutableJS data structures, where a === comparison won't work. With ap, that's as simple as this:

    import { ok } from 'true-myth/result';
    import Immutable from 'immutable';
    import { curry } from 'lodash'
    
    const is = curry(Immutable.is);
    
    const x = ok(Immutable.Set.of(1, 2, 3));
    const y = ok(Immutable.Set.of(2, 3, 4));
    
    ok(is).ap(x).ap(y); // Ok(false)

    Without ap, we're back to that gnarly nested match:

    import Result, { ok, err } from 'true-myth/result';
    import Immutable from 'immutable';
    import { curry } from 'lodash'
    
    const is = curry(Immutable.is);
    
    const x = ok(Immutable.Set.of(1, 2, 3));
    const y = ok(Immutable.Set.of(2, 3, 4));
    
    x.match({
    Ok: iX => y.match({
    Ok: iY => Result.of(Immutable.is(iX, iY)),
    Err: (e) => ok(false),
    })
    Err: (e) => ok(false),
    }); // Ok(false)

    In summary: anywhere you have two Maybe instances and need to perform an operation that uses both of them, ap is your friend.

    Two things to note, both regarding currying:

    1. All functions passed to ap must be curried. That is, they must be of the form (for add) (a: number) => (b: number) => a + b, not the more usual (a: number, b: number) => a + b you see in JavaScript more generally.

    For convenience, you may want to look at Lodash's _.curry or Ramda's R.curry, which allow you to create curried versions of functions whenever you want:

    import Result from 'true-myth/result';
    import { curry } from 'lodash';
    
    const normalAdd = (a: number, b: number) => a + b;
    const curriedAdd = curry(normalAdd); // (a: number) => (b: number) => a + b;
    
    Result.of(curriedAdd).ap(Result.of(1)).ap(Result.of(5)); // Ok(6)
    1. You will need to call ap as many times as there are arguments to the function you're dealing with. So in the case of add, which has the "arity" (function argument count) of 2 (a and b), you'll need to call ap twice: once for a, and once for b. To see why, let's look at what the result in each phase is:
    const add = (a: number) => (b: number) => a + b;
    
    const maybeAdd = Result.of(add); // Ok((a: number) => (b: number) => a + b)
    const maybeAdd1 = maybeAdd.ap(Result.of(1)); // Ok((b: number) => 1 + b)
    const final = maybeAdd1.ap(Result.of(3)); // Ok(4)

    So for toString, which just takes a single argument, you would only need to call ap once.

    const toStr = (v: { toString(): string }) => v.toString();
    Result.of(toStr).ap(12); // Ok("12")

    One other scenario which doesn't come up quite as often but is conceivable is where you have something that may or may not actually construct a function for handling a specific Result scenario. In that case, you can wrap the possibly-present in ap and then wrap the values to apply to the function to in Result themselves.

    Because Result often requires you to type out the full type parameterization on a regular basis, it's convenient to use TypeScript's typeof operator to write out the type of a curried function. For example, if you had a function that simply merged three strings, you might write it like this:

    import Result from 'true-myth/result';
    import { curry } from 'lodash';
    
    const merge3Strs = (a: string, b: string, c: string) => string;
    const curriedMerge = curry(merge3Strs);
    
    const fn = Result.ok<typeof curriedMerge, string>(curriedMerge);

    The alternative is writing out the full signature long-form:

    const fn = Result.ok<(a: string) => (b: string) => (c: string) => string, string>(curriedMerge);

    Aside:* ap is not named apply because of the overlap with JavaScript's existing apply function – and although strictly speaking, there isn't any direct overlap (Result.apply and Function.prototype.apply don't intersect at all) it's useful to have a different name to avoid implying that they're the same.

    Type parameters

    • T

    • U

    • E

    Parameters

    • resultFn: Result<function, E>

      result of a function from T to U

    • result: Result<T, E>

      result of a T to apply to fn

    Returns Result<U, E>

  • Type parameters

    • T

    • U

    • E

    Parameters

    • resultFn: Result<function, E>

    Returns function

equals

  • equals<T, E>(resultB: Result<T, E>, resultA: Result<T, E>): boolean
  • equals<T, E>(resultB: Result<T, E>): function
  • Allows quick triple-equal equality check between the values inside two results without having to unwrap them first.

    const a = Result.of(3)
    const b = Result.of(3)
    const c = Result.of(null)
    const d = Result.nothing()
    
    Result.equals(a, b) // true
    Result.equals(a, c) // false
    Result.equals(c, d) // true

    Type parameters

    • T

    • E

    Parameters

    • resultB: Result<T, E>

      A maybe to compare to.

    • resultA: Result<T, E>

      A maybe instance to check.

    Returns boolean

  • Type parameters

    • T

    • E

    Parameters

    Returns function

      • (resultA: Result<T, E>): boolean
      • Parameters

        Returns boolean

err

  • Create an instance of Result.Error.

    If you need to create an instance with a specific type (as you do whenever you are not constructing immediately for a function return or as an argument to a function), you can use a type parameter:

    const notString = Result.err<number, string>('something went wrong');

    Note: null is allowed by the type signature so that so that the function may be used to throw on passing null rather than constructing a type like Result<null, string>. undefined is allowed as a convenience method for constructing a Result<Unit, E>.

    const normalResult = Result.err<number, string>('oh no');
    const explicitUnit = Result.err<number, Unit>(Unit);
    const implicitUnit = Result.err<number, Unit>();

    In the context of an immediate function return, or an arrow function with a single expression value, you do not have to specify the types, so this can be quite convenient.

    type SomeData = {
    //...
    };
    
    const isValid = (data: SomeData): boolean => {
    // true or false...
    }
    
    const arrowValidate = (data: SomeData): Result<number, Unit> =>
    isValid(data) ? Result.ok(42) : Result.err();
    
    function fnValidate(data: someData): Result<number, Unit> {
    return isValid(data) ? Result.ok(42) : Result.err();
    }

    Type parameters

    • T

      The type of the item contained in the Result.

    • E

      The error value to wrap in a Result.Err.

    Returns Result<T, Unit>

  • Type parameters

    • T

    • E

    Parameters

    • error: E

    Returns Result<T, E>

fromMaybe

  • fromMaybe<T, E>(errValue: E, maybe: Maybe<T>): Result<T, E>
  • fromMaybe<T, E>(errValue: E): function
  • Transform a Maybe into a Result.

    If the Maybe is a Just, its value will be wrapped in the Ok variant; if it is a Nothing the errValue will be wrapped in the Err variant.

    Type parameters

    • T

    • E

    Parameters

    • errValue: E

      A value to wrap in an Err if maybe is a Nothing.

    • maybe: Maybe<T>

      The Maybe to convert to a Result.

    Returns Result<T, E>

  • Type parameters

    • T

    • E

    Parameters

    • errValue: E

    Returns function

isErr

  • isErr<T, E>(result: Result<T, E>): result is Err<T, E>
  • Is this Result an Err instance?

    In TypeScript, narrows the type from Result<T, E> to Err<T, E>.

    Type parameters

    • T

    • E

    Parameters

    Returns result is Err<T, E>

isInstance

  • isInstance<T, E>(item: any): item is Result<T, E>
  • Determine whether an item is an instance of Just or Nothing.

    Type parameters

    • T

    • E

    Parameters

    • item: any

      The item to check.

    Returns item is Result<T, E>

isOk

  • isOk<T, E>(result: Result<T, E>): result is Ok<T, E>
  • Is this Result an Ok instance?

    In TypeScript, narrows the type from Result<T, E> to Ok<T, E>.

    Type parameters

    • T

    • E

    Parameters

    Returns result is Ok<T, E>

map

  • map<T, U, E>(mapFn: function, result: Result<T, E>): Result<U, E>
  • map<T, U, E>(mapFn: function): function
  • Map over a Result instance: apply the function to the wrapped value if the instance is Ok, and return the wrapped error value wrapped as a new Err of the correct type (Result<U, E>) if the instance is Err.

    Result.map works a lot like Array.prototype.map, but with one important difference. Both Result and Array are containers for other kinds of items, but where Array.prototype.map has 0 to n items, a Result always has exactly one item, which is either a success or an error instance.

    Where Array.prototype.map will apply the mapping function to every item in the array (if there are any), Result.map will only apply the mapping function to the (single) element if an Ok instance, if there is one.

    If you have no items in an array of numbers named foo and call foo.map(x => x + 1), you'll still some have an array with nothing in it. But if you have any items in the array ([2, 3]), and you call foo.map(x => x + 1) on it, you'll get a new array with each of those items inside the array "container" transformed ([3, 4]).

    With Result.map, the Err variant is treated by the map function kind of the same way as the empty array case: it's just ignored, and you get back a new Result that is still just the same Err instance. But if you have an Ok variant, the map function is applied to it, and you get back a new Result with the value transformed, and still wrapped in an Ok.

    Examples

    import { ok, err, map, toString } from 'true-myth/result';
    const double = n => n * 2;
    
    const anOk = ok(12);
    const mappedOk = map(double, anOk);
    console.log(toString(mappedOk)); // Ok(24)
    
    const anErr = err("nothing here!");
    const mappedErr = map(double, anErr);
    console.log(toString(mappedOk)); // Err(nothing here!)

    Type parameters

    • T

      The type of the value wrapped in an Ok instance, and taken as the argument to the mapFn.

    • U

      The type of the value wrapped in the new Ok instance after applying mapFn, that is, the type returned by mapFn.

    • E

      The type of the value wrapped in an Err instance.

    Parameters

    • mapFn: function

      The function to apply the value to if result is Ok.

        • (t: T): U
        • Parameters

          • t: T

          Returns U

    • result: Result<T, E>

      The Result instance to map over.

    Returns Result<U, E>

    A new Result with the result of applying mapFn to the value in an Ok, or else the original Err value wrapped in the new instance.

  • Type parameters

    • T

    • U

    • E

    Parameters

    • mapFn: function
        • (t: T): U
        • Parameters

          • t: T

          Returns U

    Returns function

mapErr

  • mapErr<T, E, F>(mapErrFn: function, result: Result<T, E>): Result<T, F>
  • mapErr<T, E, F>(mapErrFn: function): function
  • Map over a Result, exactly as in map, but operating on the value wrapped in an Err instead of the value wrapped in the Ok. This is handy for when you need to line up a bunch of different types of errors, or if you need an error of one shape to be in a different shape to use somewhere else in your codebase.

    Examples

    import { ok, err, mapErr, toString } from 'true-myth/result';
    
    const reason = (err: { code: number, reason: string }) => err.reason;
    
    const anOk = ok(12);
    const mappedOk = mapErr(reason, anOk);
    console.log(toString(mappedOk));  // Ok(12)
    
    const anErr = err({ code: 101, reason: 'bad file' });
    const mappedErr = mapErr(reason, anErr);
    console.log(toString(mappedErr));  // Err(bad file)

    Type parameters

    • T

      The type of the value wrapped in the Ok of the Result.

    • E

      The type of the value wrapped in the Err of the Result.

    • F

      The type of the value wrapped in the Err of a new Result, returned by the mapErrFn.

    Parameters

    • mapErrFn: function

      The function to apply to the value wrapped in Err if result is an Err.

        • (e: E): F
        • Parameters

          • e: E

          Returns F

    • result: Result<T, E>

      The Result instance to map over an error case for.

    Returns Result<T, F>

  • Type parameters

    • T

    • E

    • F

    Parameters

    • mapErrFn: function
        • (e: E): F
        • Parameters

          • e: E

          Returns F

    Returns function

mapOr

  • mapOr<T, U, E>(orU: U, mapFn: function, result: Result<T, E>): U
  • mapOr<T, U, E>(orU: U, mapFn: function): function
  • mapOr<T, U, E>(orU: U): function
  • Map over a Result instance as in map and get out the value if result is an Ok, or return a default value if result is an Err.

    Examples

    import { ok, err, mapOr } from 'true-myth/result';
    
    const length = (s: string) => s.length;
    
    const anOkString = ok('a string');
    const theStringLength = mapOr(0, anOkString);
    console.log(theStringLength);  // 8
    
    const anErr = err('uh oh');
    const anErrMapped = mapOr(0, anErr);
    console.log(anErrMapped);  // 0

    Type parameters

    • T

    • U

    • E

    Parameters

    • orU: U

      The default value to use if result is an Err.

    • mapFn: function

      The function to apply the value to if result is an Ok.

        • (t: T): U
        • Parameters

          • t: T

          Returns U

    • result: Result<T, E>

      The Result instance to map over.

    Returns U

  • Type parameters

    • T

    • U

    • E

    Parameters

    • orU: U
    • mapFn: function
        • (t: T): U
        • Parameters

          • t: T

          Returns U

    Returns function

      • Parameters

        Returns U

  • Type parameters

    • T

    • U

    • E

    Parameters

    • orU: U

    Returns function

      • (mapFn: function): function
      • Parameters

        • mapFn: function
            • (t: T): U
            • Parameters

              • t: T

              Returns U

        Returns function

          • Parameters

            Returns U

mapOrElse

  • mapOrElse<T, U, E>(orElseFn: function, mapFn: function, result: Result<T, E>): U
  • mapOrElse<T, U, E>(orElseFn: function, mapFn: function): function
  • mapOrElse<T, U, E>(orElseFn: function): function
  • Map over a Result instance as in map and get out the value if result is Ok, or apply a function (orElseFn) to the value wrapped in the Err to get a default value.

    Like mapOr but using a function to transform the error into a usable value instead of simply using a default value.

    Examples

    import { ok, err, mapOrElse } from 'true-myth/result';
    
    const summarize = (s: string) => `The response was: '${s}'`;
    const getReason = (err: { code: number, reason: string }) => err.reason;
    
    const okResponse = ok("Things are grand here.");
    const mappedOkAndUnwrapped = mapOrElse(getReason, summarize, okResponse);
    console.log(mappedOkAndUnwrapped);  // The response was: 'Things are grand here.'
    
    const errResponse = err({ code: 500, reason: 'Nothing at this endpoint!' });
    const mappedErrAndUnwrapped = mapOrElse(getReason, summarize, errResponse);
    console.log(mappedErrAndUnwrapped);  // Nothing at this endpoint!

    Type parameters

    • T

      The type of the wrapped Ok value.

    • U

      The type of the resulting value from applying mapFn to the Ok value or orElseFn to the Err value.

    • E

      The type of the wrapped Err value.

    Parameters

    • orElseFn: function

      The function to apply to the wrapped Err value to get a usable value if result is an Err.

        • (err: E): U
        • Parameters

          • err: E

          Returns U

    • mapFn: function

      The function to apply to the wrapped Ok value if result is an Ok.

        • (t: T): U
        • Parameters

          • t: T

          Returns U

    • result: Result<T, E>

      The Result instance to map over.

    Returns U

  • Type parameters

    • T

    • U

    • E

    Parameters

    • orElseFn: function
        • (err: E): U
        • Parameters

          • err: E

          Returns U

    • mapFn: function
        • (t: T): U
        • Parameters

          • t: T

          Returns U

    Returns function

      • Parameters

        Returns U

  • Type parameters

    • T

    • U

    • E

    Parameters

    • orElseFn: function
        • (err: E): U
        • Parameters

          • err: E

          Returns U

    Returns function

      • (mapFn: function): function
      • Parameters

        • mapFn: function
            • (t: T): U
            • Parameters

              • t: T

              Returns U

        Returns function

          • Parameters

            Returns U

match

  • match<T, E, A>(matcher: Matcher<T, E, A>, result: Result<T, E>): A
  • match<T, E, A>(matcher: Matcher<T, E, A>): function
  • Performs the same basic functionality as getOrElse, but instead of simply unwrapping the value if it is Ok and applying a value to generate the same default type if it is Nothing, lets you supply functions which may transform the wrapped type if it is Ok or get a default value for Nothing.

    This is kind of like a poor man's version of pattern matching, which JavaScript currently lacks.

    Instead of code like this:

    import { Result, isOk, match } from 'true-myth/result';
    
    const logValue = (mightBeANumber: Result<number, string>) => {
    console.log(
    isOk(mightBeANumber)
    ? unsafelyUnwrap(mightBeANumber).toString()
    : `There was an error: ${unsafelyGetErr(mightBeANumber)}`
    );
    };

    ...we can write code like this:

    import { Result, match } from 'true-myth/result';
    
    const logValue = (mightBeANumber: Result<number, string>) => {
    const value = match(
    {
    Ok: n => n.toString(),
    Err: e => `There was an error: ${e}`,
    },
    mightBeANumber
    );
    console.log(value);
    };

    This is slightly longer to write, but clearer: the more complex the resulting expression, the hairer it is to understand the ternary. Thus, this is especially convenient for times when there is a complex result, e.g. when rendering part of a React component inline in JSX/TSX.

    Type parameters

    • T

    • E

    • A

    Parameters

    • matcher: Matcher<T, E, A>

      A lightweight object defining what to do in the case of each variant.

    • result: Result<T, E>

    Returns A

  • Type parameters

    • T

    • E

    • A

    Parameters

    Returns function

      • Parameters

        Returns A

ok

  • Create an instance of Result.Ok.

    If you need to create an instance with a specific type (as you do whenever you are not constructing immediately for a function return or as an argument to a function), you can use a type parameter:

    const yayNumber = Result.ok<number, string>(12);

    Note: null is allowed by the type signature so that so that the function may be used to throw on passing null rather than constructing a type like Result<null, string>. undefined is allowed as a convenience method for constructing a Result<Unit, E>.

    const normalResult = Result.ok<number, string>(42);
    const explicitUnit = Result.ok<Unit, string>(Unit);
    const implicitUnit = Result.ok<Unit, string>();

    In the context of an immediate function return, or an arrow function with a single expression value, you do not have to specify the types, so this can be quite convenient.

    type SomeData = {
    //...
    };
    
    const isValid = (data: SomeData): boolean => {
    // true or false...
    }
    
    const arrowValidate = (data: SomeData): Result<Unit, string> =>
    isValid(data) ? Result.ok() : Result.err('something was wrong!');
    
    function fnValidate(data: someData): Result<Unit, string> {
    return isValid(data) ? Result.ok() : Result.err('something was wrong');
    }

    Type parameters

    • T

      The type of the item contained in the Result.

    • E

    Returns Result<Unit, E>

  • Type parameters

    • T

    • E

    Parameters

    • value: T

    Returns Result<T, E>

or

  • or<T, E, F>(defaultResult: Result<T, F>, result: Result<T, E>): Result<T, F>
  • or<T, E, F>(defaultResult: Result<T, F>): function
  • Provide a fallback for a given Result. Behaves like a logical or: if the result value is an Ok, returns that result; otherwise, returns the defaultResult value.

    This is useful when you want to make sure that something which takes a Result always ends up getting an Ok variant, by supplying a default value for the case that you currently have an Err.

    import { ok, err, Result, or } from 'true-utils/result';
    
    const okA = ok<string, string>('a');
    const okB = ok<string, string>('b');
    const anErr = err<string, string>(':wat:');
    const anotherErr = err<string, string>(':headdesk:');
    
    console.log(or(okB, okA).toString());  // Ok(A)
    console.log(or(anErr, okA).toString());  // Ok(A)
    console.log(or(okB, anErr).toString());  // Ok(B)
    console.log(or(anotherErr, anErr).toString());  // Err(:headdesk:)

    Type parameters

    • T

      The type wrapped in the Ok case of result.

    • E

      The type wrapped in the Err case of result.

    • F

      The type wrapped in the Err case of defaultResult.

    Parameters

    • defaultResult: Result<T, F>

      The Result to use if result is an Err.

    • result: Result<T, E>

      The Result instance to check.

    Returns Result<T, F>

    result if it is an Ok, otherwise defaultResult.

  • Type parameters

    • T

    • E

    • F

    Parameters

    Returns function

orElse

  • orElse<T, E, F>(elseFn: function, result: Result<T, E>): Result<T, F>
  • orElse<T, E, F>(elseFn: function): function
  • Like or, but using a function to construct the alternative Result.

    Sometimes you need to perform an operation using other data in the environment to construct the fallback value. In these situations, you can pass a function (which may be a closure) as the elseFn to generate the fallback Result<T>. It can then transform the data in the Err to something usable as an Ok, or generate a new Err instance as appropriate.

    Useful for transforming failures to usable data.

    Type parameters

    • T

    • E

    • F

    Parameters

    • elseFn: function

      The function to apply to the contents of the Err if result is an Err, to create a new Result.

        • Parameters

          • err: E

          Returns Result<T, F>

    • result: Result<T, E>

      The Result to use if it is an Ok.

    Returns Result<T, F>

    The result if it is Ok, or the Result returned by elseFn if result is an `Err.

  • Type parameters

    • T

    • E

    • F

    Parameters

    • elseFn: function
        • Parameters

          • err: E

          Returns Result<T, F>

    Returns function

Const toJSON

  • Create an Object representation of a Result instance.

    Useful for serialization. JSON.stringify() uses it.

    Type parameters

    • T

    • E

    Parameters

    • result: Result<T, E>

      The value to convert to JSON

    Returns ResultJSON<T, E>

    The JSON representation of the Result

toMaybe

  • Convert a Result to a Maybe.

    The converted type will be Just if the Result is Ok or Nothing if the Result is Err; the wrapped error value will be discarded.

    Type parameters

    • T

    Parameters

    • result: Result<T, any>

      The Result to convert to a Maybe

    Returns Maybe<T>

    Just the value in result if it is Ok; otherwise Nothing

Const toString

  • toString<T, E>(result: Result<T, E>): string
  • Create a String representation of a result instance.

    An Ok instance will be printed as Ok(<representation of the value>), and an Err instance will be printed as Err(<representation of the error>), where the representation of the value or error is simply the value or error's own toString representation. For example:

    call output
    toString(ok(42)) Ok(42)
    toString(ok([1, 2, 3])) Ok(1,2,3)
    toString(ok({ an: 'object' })) Ok([object Object])n
    toString(err(42)) Err(42)
    toString(err([1, 2, 3])) Err(1,2,3)
    toString(err({ an: 'object' })) Err([object Object])

    Type parameters

    • T: object

      The type of the wrapped value; its own .toString will be used to print the interior contents of the Just variant.

    • E: object

    Parameters

    Returns string

    The string representation of the Maybe.

tryOr

  • tryOr<T, E>(error: E, callback: function): Result<T, E>
  • tryOr<T, E>(error: E): function
  • Execute the provided callback, wrapping the return value in Result.Ok or Result.Err(error) if there is an exception.

    const aSuccessfulOperation = () => 2 + 2;
    
    const anOkResult = Result.tryOr('Oh noes!!1', () => {
    aSuccessfulOperation()
    }); // => Ok(4)
    
    const thisOperationThrows = () => throw new Error('Bummer');
    
    const anErrResult = Result.tryOr('Oh noes!!1', () => {
    thisOperationThrows();
    }); // => Err('Oh noes!!1')

    Type parameters

    • T

    • E

    Parameters

    • error: E

      The error value in case of an exception

    • callback: function

      The callback to try executing

        • (): T
        • Returns T

    Returns Result<T, E>

  • Type parameters

    • T

    • E

    Parameters

    • error: E

    Returns function

      • (callback: function): Result<T, E>
      • Parameters

        • callback: function
            • (): T
            • Returns T

        Returns Result<T, E>

tryOrElse

  • tryOrElse<T, E>(onError: function, callback: function): Result<T, E>
  • tryOrElse<T, E>(onError: function): function
  • Execute the provided callback, wrapping the return value in Result.Ok. If there is an exception, return a Result.Err of whatever the onError function returns.

    const aSuccessfulOperation = () => 2 + 2;
    
    const anOkResult = Result.tryOrElse(
    (e) => e,
    aSuccessfulOperation
    ); // => Ok(4)
    
    const thisOperationThrows = () => throw 'Bummer'
    
    const anErrResult = Result.tryOrElse((e) => e, () => {
    thisOperationThrows();
    }); // => Err('Bummer')

    Type parameters

    • T

    • E

    Parameters

    • onError: function

      A function that takes e exception and returns what will be wrapped in a Result.Err

        • (e: unknown): E
        • Parameters

          • e: unknown

          Returns E

    • callback: function

      The callback to try executing

        • (): T
        • Returns T

    Returns Result<T, E>

  • Type parameters

    • T

    • E

    Parameters

    • onError: function
        • (e: unknown): E
        • Parameters

          • e: unknown

          Returns E

    Returns function

      • (callback: function): Result<T, E>
      • Parameters

        • callback: function
            • (): T
            • Returns T

        Returns Result<T, E>

unsafelyUnwrap

  • unsafelyUnwrap<T, E>(result: Result<T, E>): T
  • Get the value out of the Result.

    Returns the content of an Ok, but throws if the Result is Err. Prefer to use unwrapOr or unwrapOrElse.

    throws

    If the Result instance is Nothing.

    Type parameters

    • T

    • E

    Parameters

    Returns T

unsafelyUnwrapErr

  • unsafelyUnwrapErr<T, E>(result: Result<T, E>): E
  • Get the error value out of the Result.

    Returns the content of an Err, but throws if the Result is Ok. Prefer to use unwrapOrElse.

    throws

    Error If the Result instance is Nothing.

    Type parameters

    • T

    • E

    Parameters

    Returns E

unwrapOr

  • unwrapOr<T, E>(defaultValue: T, result: Result<T, E>): T
  • unwrapOr<T, E>(defaultValue: T): function
  • Safely get the value out of the Ok variant of a Result.

    This is the recommended way to get a value out of a Result most of the time.

    import { ok, err, unwrapOr } from 'true-myth/result';
    
    const anOk = ok<number, string>(12);
    console.log(unwrapOr(0, anOk));  // 12
    
    const anErr = err<number, string>('nooooo');
    console.log(unwrapOr(0, anErr));  // 0

    Type parameters

    • T

      The value wrapped in the Ok.

    • E

      The value wrapped in the Err.

    Parameters

    • defaultValue: T

      The value to use if result is an Err.

    • result: Result<T, E>

      The Result instance to unwrap if it is an Ok.

    Returns T

    The content of result if it is an Ok, otherwise defaultValue.

  • Type parameters

    • T

    • E

    Parameters

    • defaultValue: T

    Returns function

      • Parameters

        Returns T

unwrapOrElse

  • unwrapOrElse<T, E>(orElseFn: function, result: Result<T, E>): T
  • unwrapOrElse<T, E>(orElseFn: function): function
  • Safely get the value out of a Result by returning the wrapped value if it is Ok, or by applying orElseFn to the value in the Err.

    This is useful when you need to generate a value (e.g. by using current values in the environment – whether preloaded or by local closure) instead of having a single default value available (as in unwrapOr).

    import { ok, err, unwrapOrElse } from 'true-myth/result';
    
    // You can imagine that someOtherValue might be dynamic.
    const someOtherValue = 2;
    const handleErr = (errValue: string) => errValue.length + someOtherValue;
    
    const anOk = ok<number, string>(42);
    console.log(unwrapOrElse(handleErr, anOk));  // 42
    
    const anErr = err<number, string>('oh teh noes');
    console.log(unwrapOrElse(handleErr, anErr));  // 13

    Type parameters

    • T

      The value wrapped in the Ok.

    • E

      The value wrapped in the Err.

    Parameters

    • orElseFn: function

      A function applied to the value wrapped in result if it is an Err, to generate the final value.

        • (error: E): T
        • Parameters

          • error: E

          Returns T

    • result: Result<T, E>

      The result to unwrap if it is an Ok.

    Returns T

    The value wrapped in result if it is Ok or the value returned by orElseFn applied to the value in Err.

  • Type parameters

    • T

    • E

    Parameters

    • orElseFn: function
        • (error: E): T
        • Parameters

          • error: E

          Returns T

    Returns function

      • Parameters

        Returns T

Object literals

Const Result

Result: object

Err

Err: Err

Ok

Ok: Ok

Variant

Variant: Variant

and

and: and

andThen

andThen: andThen

ap

ap: ap

cata

cata: match

chain

chain: andThen

equals

equals: equals

err

err: err

flatMap

flatMap: andThen

fromMaybe

fromMaybe: fromMaybe

getOr

getOr: unwrapOr

getOrElse

getOrElse: unwrapOrElse

isErr

isErr: isErr

isInstance

isInstance: isInstance

isOk

isOk: isOk

map

map: map

mapErr

mapErr: mapErr

mapOr

mapOr: mapOr

mapOrElse

mapOrElse: mapOrElse

match

match: match

ok

ok: ok

or

or: or

orElse

orElse: orElse

toJSON

toJSON: toJSON

toMaybe

toMaybe: toMaybe

toString

toString: toString

tryOr

tryOr: tryOr

tryOrElse

tryOrElse: tryOrElse

unsafeGet

unsafeGet: unsafelyUnwrap

unsafelyGet

unsafelyGet: unsafelyUnwrap

unsafelyGetErr

unsafelyGetErr: unsafelyUnwrapErr

unsafelyUnwrap

unsafelyUnwrap: unsafelyUnwrap

unsafelyUnwrapErr

unsafelyUnwrapErr: unsafelyUnwrapErr

unwrapOr

unwrapOr: unwrapOr

unwrapOrElse

unwrapOrElse: unwrapOrElse

Generated using TypeDoc