neverthrow icon indicating copy to clipboard operation
neverthrow copied to clipboard

andThen fails to correctly infer types from result union

Open connorpb opened this issue 9 months ago • 2 comments

I love neverthrow - I'd been using a custom hacked together Result class that required a TON of annotation and have loved that neverthrow mostly gets the inferred types right. This is great because for me, a huge benefit is in relying on those inferred types to accurately keep track of error unions, etc. But sometimes neverthrow fails to infer types, specifically with "andThen".

const sync1 = (bool: boolean) => bool ? ok(true) : err("bad");
// return type Ok<boolean, never> | Err<never, "bad">

const sync2 = (bool2: boolean) => bool2 ? ok(100) : err("terrible")
// return type Ok<number, never> | Err<never, "terrible">

const sync1Annotated = (bool: boolean): Result<boolean, "bad"> => bool ? ok(true) : err("bad");
// return type collapsed by manual annotation to Result<boolean, "bad">

const test1 = (bool: boolean) => sync1(bool).andThen(result => sync2(result)) // this expression is not callable - ts(2349)
const test2 = (bool: boolean) => (sync1(bool) as Result<boolean, "bad">).andThen(result => sync2(result)) // succeeds on assertion
const test3 = (bool: boolean) => sync1(bool).andThen<Result<boolean, "bad">>(result => sync2(result)) // this expression is not callable - ts(2349)
const test4 = (bool: boolean) => sync1(bool).andThen<boolean, "bad">(result => sync2(result)) // this expression is not callable - ts(2349)
const test5 = (bool: boolean) => sync1Annotated(bool).andThen(result => sync2(result)) // succeeds when manually annotated

I've uploaded a few additional examples including async, and asyncAndThen, with what works and what fails to a minimal reproducible example repo.

Interestingly, "map" doesn't have this problem and can infer types very consistently. I'm willing to dig into it to try to come up with a PR but wanted to see if you all were aware of this previously or have any insight as to why it's happening before I go recreating the wheel!

Thanks again for such a great library.

connorpb avatar Mar 28 '25 05:03 connorpb