Skip to content

Morglod/go-result-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NPM Version Coverage

go-result-js

Go-like results:

const [ err, result ] = foo();
  • Zero dependencies
  • Full typescript support
  • 100% test coverage

Usage

Install:

npm i go-result-js

Import:

import { ResultA, ResultErr, ResultOk } from 'go-result-js';

Or use it globally:
(write in main file, before everythink)

import 'go-result-js/lib/global';

Example with exceptions

Before:

const result = await doSmthWithException();
// (node:17320) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Request failed with status code 400
// (node:17320) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

After:

const [ err, result ] = await ResultA(doSmthWithException());
if (err || !result) {
    // exception handled!
}

Example

function divide(a: number, b: number): Result<number> {
    if (b === 0) return ResultErr('Can not divide by zero!');
    return ResultOk(a / b);
}

function main() {
    const [ err, result ] = divide(10, 5);

    if (err) console.error(err);
    else console.log('success', result);
}

Example with async

const asyncDivide = (a: number, b: number): ResultA<number> => ResultA<number>(resolve => {
    resolve(b === 0 ? new Error('Can not divide by zero!') : a / b);
});

async function asyncMain() {
    const [ err, result ] = await asyncDivide(10, 5);

    if (err) console.error(err);
    else console.log('success', result);
}

Example with AWS

import { Auth } from 'aws-amplify';

export async function main() {
    const [ err, user ] = await ResultA(Auth.signIn('root', 'password'));
}

Multiple results

Handle multiple ResultA results, and catch any errors.

const { err, values } = await resultAll(
    Content.fetchById(contentType, id),
    Rubrics.fetchRubrics(),
    ContentTypes.fetchContentTypes(),
);

if (err) {
    // on any error
}

const {
    0: content,
    1: rubrics,
    2: contentTypes,
} = values;

API

Types
export type ResultErr<ErrorT extends Error = Error> = ErrorT|true|undefined;
export type Result<T, ErrorT extends Error = Error> = [ ResultErr<ErrorT>, T|undefined ];
export type ResultA<T, ErrorT extends Error = Error> = Promise<Result<T, ErrorT>>;
Methods
function registerGlobally(global?: any): Result<boolean>

Assign all methods to global object.
go-result-js/lib/global calls it.

function ResultOk<T>(value: T): Result<T>

Returns value with undefined error.

function ResultErr<ErrorT extends Error, T=any>(err: ErrorT|true|string = true): Result<T, ErrorT>

Returns error with undefined value.

function ResultA<T, ErrorT extends Error>(
    x: Promise<T> | ((
        resolve: (value: undefined|T|Error) => void,
        reject: (err?: ErrorT) => void
    ) => void)
): ResultA<T, ErrorT>

Takes Promise's callbacks or Promise, catch it's error and resolve as Promise<Result>.

function resultAll<Results extends ResultA<any>[]>(
    ...results: Results
): Promise<{
    err: ResultErr | undefined,
    values: {
        [i in keyof Results]: PickSecondItem<PromiseType<Results[i]>, undefined>
    },
    results: {
        [i in keyof Results]: PromiseType<Results[i]>
    }
}>

Releases

No releases published

Packages

No packages published