neverthrow icon indicating copy to clipboard operation
neverthrow copied to clipboard

feat: fork()

Open timvandam opened this issue 9 months ago • 4 comments

https://github.com/supermacro/neverthrow/issues/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)

timvandam avatar Mar 03 '25 08:03 timvandam

🦋 Changeset detected

Latest commit: dbf26715dacccfe8ab31c1b44775b57c8ba45b19

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

changeset-bot[bot] avatar Mar 03 '25 08:03 changeset-bot[bot]

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

timvandam avatar Mar 19 '25 12:03 timvandam

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

timvandam avatar May 18 '25 10:05 timvandam

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

timvandam avatar Oct 29 '25 14:10 timvandam