diff --git a/src/async/errorFirst.ts b/src/async/errorFirst.ts new file mode 100644 index 00000000..099d696a --- /dev/null +++ b/src/async/errorFirst.ts @@ -0,0 +1,34 @@ +import { isFunction } from 'radashi' + +const left = (error: Error): [Error, null] => [error, null] +const right = (value: T): [null, T] => [null, value] + +export type ErrorFirst = [null, T] | [Error, null] + +/** + * Call an async function and return a promise that resolves to an + * array of the error and the value. + * + * - If the promise resolves, the result is `[null, value]`. + * - If the promise rejects, the result is `[error, null]`. + */ +export function errorFirst( + fn: (...args: Args) => Promise, + ...args: Args +): Promise> + +export function errorFirst(promise: Promise): Promise> + +export function errorFirst( + promise: Promise | ((...args: any[]) => Promise), + ...args: any[] +): Promise> { + if (isFunction(promise)) { + try { + promise = promise(...args) + } catch (error) { + promise = Promise.reject(error) + } + } + return promise.then(right, left) +} diff --git a/src/mod.ts b/src/mod.ts index 25238f89..ef862f0d 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -34,6 +34,7 @@ export * from './array/zipToObject.ts' export * from './async/AggregateError.ts' export * from './async/all.ts' export * from './async/defer.ts' +export * from './async/errorFirst.ts' export * from './async/guard.ts' export * from './async/map.ts' export * from './async/parallel.ts'