-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"expression is not callable" with .andThen() #417
Comments
Repro was actually super simple, that stumbs me a lil: import { ok, err } from "neverthrow";
const result = Math.random() ? err("wat") : ok(42);
result.andThen(() => ok({})) |
My current workaround is to explicitly type the result type, i.e. import { Result, ok, err } from "neverthrow";
const result: Result<number, string> = Math.random() ? err("wat") : ok(42);
result.andThen(() => ok({})) I suppose something in the err/ok union or its type inference is failing, but I'm not enough of a TS geek to figure out what it is. But I'm pretty sure it's a bug, and not user error, at this point. |
Yeah I'm a bit confused as to what's going on here. I would assume it's a type inference issue having to do with Going to see if any of my colleagues know what's going on. |
that looks interesting 🕵️ , would you mind assigning me to it? 🙏 |
Done 🙂 |
I'm not sure it can actually be directly handled by clever typings from See your updated typescriptlang example. import { ok, err, type Result } from "neverthrow";
const result: Result<number, string> = Math.random() ? err("wat") : ok(42);
result.andThen(() => ok({})) Your actual function's signature could then be: function getNodeFromPath(ast: t.File, path: Path): Result<t.Node | t.Node[], string> |
I believe it is the same solution as this? It's definitely an option, though 👍 I spent a few hours on Sunday tinkering with the types, but no luck as of yet. |
@boredcity Oh... yeah, this is exactly the workaround already figured out and shared. Oops! I actually ran into a similar problem recently and did spend the few customary weekend hours of tinkering, to no avail. |
Going back to the repro - I'm still confused as to why shared methods / types would just vanish. Could it be that this happens because calling |
actually, the complete error string is
so for me, the more surprising part is and it goes away if you comment out
in Ok and
in Err (other errors appear though 😄). Still trying to fix the problem, but to no avail for now :/ |
Honestly, I think I'm ready to throw in the towel at this point 😖 |
@tam-carre @incetarik any ideas on what might be happening here? |
I'll check this out when I complete the other one 👍🏻 |
Not sure what the fix it, but I've had the need to annotate away the |
I see, in short this error occurs when the overloads are not compatible with each other. |
diff --git a/src/result.ts b/src/result.ts
index 59edf44..0291597 100644
--- a/src/result.ts
+++ b/src/result.ts
@@ -213,7 +213,6 @@ export class Ok<T, E> implements IResult<T, E> {
andThen<R extends Result<unknown, unknown>>(
f: (t: T) => R,
): Result<InferOkTypes<R>, InferErrTypes<R> | E>
- andThen<U, F>(f: (t: T) => Result<U, F>): Result<U, E | F>
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
andThen(f: any): any {
return f(this.value)
@@ -276,7 +275,6 @@ export class Err<T, E> implements IResult<T, E> {
andThen<R extends Result<unknown, unknown>>(
_f: (t: T) => R,
): Result<InferOkTypes<R>, InferErrTypes<R> | E>
- andThen<U, F>(_f: (t: T) => Result<U, F>): Result<U, E | F>
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
andThen(_f: any): any {
return err(this.error)
diff --git a/tests/typecheck-tests.ts b/tests/typecheck-tests.ts
index 8fd7ce7..178db2e 100644
--- a/tests/typecheck-tests.ts
+++ b/tests/typecheck-tests.ts
@@ -136,7 +136,7 @@ import { Transpose } from '../src/result'
(function it(_ = 'allows specifying the E and T types explicitly') {
type Expectation = Result<'yo', number>
- const result: Expectation = ok(123).andThen<'yo', number>(val => {
+ const result: Expectation = ok(123).andThen<Result<'yo', number>>(val => {
return ok('yo')
})
}); This patch fixes the original issue but introduces a new one: the need to explicitely set the template parameters for In my personal use of neverthrow I never explicitely type instance methods like this, but I do run into the issue OP mentioned quite often. The patch will also cause breaking changes if people relied on explicitely typing Just thought I'd share this finding. |
Hi. |
Hi there,
thanks for the amazing lib, love using every chance to make JS more Rusty and safe.
I did not manage to get a minimal repro yet, but I thought I'd post already in case someone has an idea.
This is the type signature of my Result-returning-function:
Unfortunately I get
This expression is not callable.
when calling.andThen()
on it. Curiously enough.map()
works.Any ideas?
The text was updated successfully, but these errors were encountered: