Skip to content

Conversation

@timvandam
Copy link

@timvandam timvandam commented Mar 3, 2025

#594

fork() allows you to handle Ok<.> and Err<.> at once. This is similar to Promise:then(a, b), which is not the same as Promise .then(a).catch(b) nor .catch(b).then(a) (see image https://stackoverflow.com/a/24663315)

While match() could already be used to achieve this for Result<A, B> by simply returning a Result<T, U> in either branch, this approach falls apart for ResultAsync, as match() makes the return type to be a promise. Fork() is especially useful in this case, as it allows you to chain methods available on ResultAsync.

// We can chain on .match() by returning a Result<.>
const matchExample1 = ok(123)
  .match(
    (x) => ok(x + 321),
    (y) => err(y + 444),
  )
  .map((x) => x - 321)

// We cannot do the same when using .match() on ResultAsync<.>
const asyncMatchExample1 = okAsync(123)
  .match(
    (x) => okAsync(x + 321),
    (y) => errAsync(y + 444),
  )
  // TS2339: Property map does not exist on type
  // Promise<ResultAsync<number, never> | ResultAsync<never, number>>
  .map((x) => x - 321)

// To be able to chain on ResultAsync<.>:match we must currently use fromSafePromise(.).andThen(x => x)
const asyncMatchExample1Fixed = fromSafePromise(
  okAsync(123).match(
    (x) => okAsync(x + 321),
    (y) => errAsync(y + 444),
  ),
)
  // flatten
  .andThen((x) => x)
  .map((x) => x - 321)

// .fork() works just like .match() on Result<.> (except its handlers must return a Result<.>)
const forkExample1 = ok(123)
  .fork(
    (x) => ok(x + 321),
    (y) => err(y + 444),
  )
  .map((x) => x - 321)

// We no longer need fromSafePromise(.).andThen(x=>x) when matching on ResultAsync
const asyncForkExample1 = okAsync(123)
  .fork(
    (x) => ok(x + 321),
    (y) => err(y + 444),
  )
  .map((x) => x - 321)

@changeset-bot
Copy link

changeset-bot bot commented Mar 3, 2025

🦋 Changeset detected

Latest commit: dbf2671

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

@timvandam timvandam force-pushed the master branch 2 times, most recently from 2b44376 to 6fa68e5 Compare March 3, 2025 09:35
@timvandam
Copy link
Author

Hi @supermacro! Do you think you could review this sometime soon? Thanks!

@timvandam
Copy link
Author

timvandam commented May 18, 2025

@supermacro @m-shaka any chance you could review this / let me know if this has no chance of making it in?

@timvandam
Copy link
Author

Hi @supermacro @m-shaka. Any chance of this being reviewed?

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.

1 participant