diff --git a/src/_internals/utils.ts b/src/_internals/utils.ts index 6c108b0d..04196144 100644 --- a/src/_internals/utils.ts +++ b/src/_internals/utils.ts @@ -27,23 +27,24 @@ export type InferErrTypes = R extends Result ? E : never export type InferAsyncOkTypes = R extends ResultAsync ? T : never export type InferAsyncErrTypes = R extends ResultAsync ? E : never -const appendValueToEndOfList = (value: T) => (list: T[]): T[] => [...list, value] - /** * Short circuits on the FIRST Err value that we find */ export const combineResultList = ( resultList: readonly Result[], -): Result => - resultList.reduce( - (acc, result) => - acc.isOk() - ? result.isErr() - ? err(result.error) - : acc.map(appendValueToEndOfList(result.value)) - : acc, - ok([]) as Result, - ) +): Result => { + let acc = ok([]) as Result + + for (const result of resultList) { + if (result.isErr()) { + acc = err(result.error) + break + } else { + acc.map((list) => list.push(result.value)) + } + } + return acc +} /* This is the typesafe version of Promise.all * @@ -62,18 +63,21 @@ export const combineResultAsyncList = ( */ export const combineResultListWithAllErrors = ( resultList: readonly Result[], -): Result => - resultList.reduce( - (acc, result) => - result.isErr() - ? acc.isErr() - ? err([...acc.error, result.error]) - : err([result.error]) - : acc.isErr() - ? acc - : ok([...acc.value, result.value]), - ok([]) as Result, - ) +): Result => { + let acc = ok([]) as Result + + for (const result of resultList) { + if (result.isErr() && acc.isErr()) { + acc.error.push(result.error) + } else if (result.isErr() && acc.isOk()) { + acc = err([result.error]) + } else if (result.isOk() && acc.isOk()) { + acc.value.push(result.value) + } + // do nothing when result.isOk() && acc.isErr() + } + return acc +} export const combineResultAsyncListWithAllErrors = ( asyncResultList: readonly ResultAsync[],