Go-like results:
const [ err, result ] = foo();
- Zero dependencies
- Full typescript support
- 100% test coverage
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';
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!
}
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);
}
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);
}
import { Auth } from 'aws-amplify';
export async function main() {
const [ err, user ] = await ResultA(Auth.signIn('root', 'password'));
}
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;
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]>
}
}>