result-box

Because throw/catch is not always best

Usage no npm install needed!

<script type="module">
  import resultBox from 'https://cdn.skypack.dev/result-box';
</script>

README

result-box

Version Build Status Coverage Dependencies Vulnerabilities License Types

Because throw/catch is not always best.

Install

npm install result-box

Usage

A result is a plain object with fields success and data. Type definitions for different kinds of result are provided, as well as some creation, operation, and consumption conveniency functions:

Result

Type definitions are provided for a successful result, a failed result, and a combination of them:

import { Result } from 'result-box';

const success: Result.Success<string> = {
  success: true,
  data: 'foo'
};

const failure: Result.Failure<Error> = {
  success: false,
  data: Error('foo')
};

const successBox: Result.Box<string, Error> = success;
const failureBox: Result.Box<string, Error> = failure;

const successBreak: Result.Break<string, Error> = success;
const failureBreak: Result.Break<string, Error> = failure;
const nullBreak: Result.Break<string, Error> = null;

Create

Creation utility functions:

import { Create } from 'result-box';

// Returns: `{ success: true, data: { foo: 'bar' } }`
const success = Create.success({ foo: 'bar' });

// Returns: `{ success: false, data: { reason: Error, code: 500 } }`
const failure = Create.failure({ reason: Error(), code: 500 });

// Returns: `{ success: true, data: { foo: 'bar' } }`
const executeSuccess = Create.execute(() => ({ foo: 'bar' }));

// Returns: `{ success: false, data: Error }`
const executeFailure = Create.execute(() => { throw Error(); });

Operate

All operations return a unary function taking a result as an argument. You can straightforwardly pipe them with a pipe function such as the ones provided by the pipettes package.

import { Result, Operate } from 'result-box';
import { into } from 'pipettes';

const none = null as Result.Break<number, string>;

// Return type: `Result.Box<number | boolean, string>`
const box = into(none, Operate.fallback(true));

// Return type: `number | boolean | string[]`
const transformed = into(
  box,
  Operate.transform(null, (data: string) => [data])
);

// Return type: `Result.Box<boolean, string>`
const mapped = into(
  box,
  Operate.map((data: number | boolean) => data === 5, null)
);

// Return type: `Result.Box<never, number | boolean | string>`
const flipped = into(box, Operate.flip(true, false));

// Return type: `Result.Box<number | boolean, string>`
const tapped = into(box, Operate.tap(null, console.log));

Consume

Consumption utility functions:

import { Create, Consume } from 'result-box';
import { into } from 'pipettes';

// Returns: `'foo'`
const data = Consume.result(Create.success('foo'));

// Throws error
into(Create.failure('bar'), Consume.result);