I think it would be useful to have a mergeFields method similar to Result.combine but which works with object fields
Usage:
const result = mergeFields({
length: parseLength(lengthString), // returns Result<number, 'InvalidLengthString'>
width: parseWidth(widthString), // returns Result<number, 'InvalidWidthString'>
})
// type of result is Result<{ length: number, width: number }, 'InvalidLengthString' | 'InvalidWidthString>
Possible implementation:
type ExtractOk<T extends Result<unknown, unknown>> = T extends Result<infer U, unknown> ? U : never
type ErrorUnion<U> = U[keyof U] extends Result<any, infer E> ? E : never;
export function mergeFields<R, E, U extends Record<string, Result<R, E>>>(results: U)
: Result<
{ [K in keyof U]: ExtractOk<U[K]> },
ErrorUnion<U>
> {
const unwrapped: Partial<Record<string, unknown>> = {};
for (const key of Object.keys(results) as Array<keyof U>) {
const r = results[key] as Result<unknown, ErrorUnion<U>>;
if (r.isErr()) {
return err(r.error);
}
unwrapped[key as string] = r.value;
}
return ok({
...(unwrapped as { [K in keyof U]: ExtractOk<U[K]> }),
} as { [K in keyof U]: ExtractOk<U[K]> });
}
I think it would be useful to have a mergeFields method similar to Result.combine but which works with object fields
Usage:
Possible implementation: