Err.andThen always returns a Result which prevents transforming a Result to a ResultAsync
See original GitHub issueThe current andThen
overloaded methods in Ok
and Err
look like this:
export declare class Ok<T, E> {
andThen<U>(f: (t: T) => ResultAsync<U, E>): ResultAsync<U, E>;
andThen<U>(f: (t: T) => Result<U, E>): Result<U, E>;
}
export declare class Err<T, E> {
andThen<U>(_f: (t: T) => Result<U, E>): Result<U, E>;
andThen<U>(_f: (t: T) => ResultAsync<U, E>): Result<U, E>;
}
Which seems to prevent me from doing things like this:
const sq = (n: number): Result<number, number> => ok(n ** 2);
const sqAsync = (n: number): ResultAsync<number, number> => okAsync(n ** 2);
ok(2)
.andThen(sq)
// ERROR
// Argument of type '(n: number) => ResultAsync<number, number>' is not assignable to parameter of type '(t: number) => Result<unknown, unknown>'.
// Type 'ResultAsync<number, number>' is not assignable to type 'Result<unknown, unknown>'.
// Type 'ResultAsync<number, number>' is missing the following properties from type 'Err<unknown, unknown>': error, isOk, isErr, asyncMap, and 2 more.ts(2345)
.andThen(sqAsync);
The above error message isn’t that useful but if you rename async andThen
methods to andTest
as such:
export declare class Ok<T, E> {
andTest<U>(f: (t: T) => ResultAsync<U, E>): ResultAsync<U, E>;
andThen<U>(f: (t: T) => Result<U, E>): Result<U, E>;
}
export declare class Err<T, E> {
andThen<U>(_f: (t: T) => Result<U, E>): Result<U, E>;
andTest<U>(_f: (t: T) => ResultAsync<U, E>): Result<U, E>;
}
and then change the example code above:
const sq = (n: number): Result<number, number> => ok(n ** 2);
const sqAsync = (n: number): ResultAsync<number, number> => okAsync(n ** 2);
ok(2)
.andThen(sq)
.andTest(sqAsync);
you get the following error:
This expression is not callable.
Each member of the union type '(<U>(f: (t: number) => ResultAsync<U, unknown>) => ResultAsync<U, unknown>) | (<U>(_f: (t: number) => ResultAsync<U, unknown>) => Result<U, unknown>)' has signatures, but none of those signatures are compatible with each other.ts(2349)
How can I take a Result
and turn it into a ResultAsync
when I have an operation that returns a Promise
?
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (9 by maintainers)
Top Results From Across the Web
How to use neverthrow with async/await through the call ...
I am currently replacing my pure Promise structure by ResultAsync. ... with async function you can just return error result right away.
Read more >Optional, throws, Result, async/await - NSHipster
We set up a query, pass an an empty inout reference to SecItemCopyMatching and then, depending on the status code we get back,...
Read more >neverthrow - npm
This package contains a Result type that represents either success ( Ok ) or failure ( Err ). For asynchronous tasks, neverthrow offers...
Read more >Discussion of Type-Safe Error Handling In TypeScript
You've changed your one "if not url, return the err result" line to not ... on any third-party libraries, there'll always be throw...
Read more >Frequently Asked Questions - Jasmine Documentation
How can I stop Jasmine from running my specs in parallel? ... the access to result.things.length will throw an error, preventing done from...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
v2.4.0
is now live on npmHey @jsmith @paduc,
Here are my thoughts.
I also agree that
andThen
(as well as any method inneverthrow
) should always have the same method signature acrossOk
andErr
instances (maybe something I should add to a contributing guidelines document).When originally doing code review for the introduction of
ResultAsync
, I overlooked this subtlety, but if I hadn’t overlooked it, I would have made the point above.I actually really like this overloaded behaviour. It reduces the surface area of API, but makes the current API multi-purpose.
I can dive into the code later today and open a PR that does this. I’m fairly confident I can implement something that works.
If it cannot be done then I may be open to adding a
asyncAndThen
method.