Skip to content

Conversation

@Karibash
Copy link

Hi @supermacro ,

First of all, I would like to thank you for creating such a wonderful library. I have been using neverthrow in a production environment for about a year and I am very satisfied with it.

In this PR, I am adding a function that combines multiple Results, passed as an object, into a single Result. This can be very useful for functional programming as shown below:

const createTaskId: (id: string) => Result<TaskId, Error>;
const createTaskContent: (content: string) => Result<TaskContent, Error>;

const task = Result.struct({
  id: createTaskId('id'),
  content: createTaskContent('content'),
});

To do the same thing with the current API, you need to use map as shown below. This requires you to remember which data is in which position in the array, which is not very convenient.

const createTaskId: (id: string) => Result<TaskId, Error>;
const createTaskContent: (content: string) => Result<TaskContent, Error>;

const values = Result.combineWithAllErrors([
  createTaskId('id'),
  createTaskContent('content'),
]);

const task = values.map(([id, content]) => ({ id, content }));

@changeset-bot
Copy link

changeset-bot bot commented Nov 12, 2024

🦋 Changeset detected

Latest commit: 595c76a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
neverthrow Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@macksal
Copy link
Contributor

macksal commented Nov 26, 2024

Faced this exact pattern before, and using ResultAsync.combine is very awkward. +1 for the feature.

My one question is, does this really need to be a different method, or would it be possible to just overload combine/combineWithAllErrors to accept either an array or an object and return the appropriate type?

I am thinking of the combineLatest function in rxjs which has that exact overload. Pass an array of observables, get an observable of arrays. Pass an object of observables, get an observable of objects.

We could have similarly (for Result.combine):

  • pass an array of results, get a result of array
  • pass an object of results, get a result of object

overloads can be messy, but I'm more favourable of them in library code where the user is more likely to see these two cases as equivalent, and it avoids the need for them to remember any difference in behaviour between the two if they are truly analogous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants