gigobyte / purify

Functional programming library for TypeScript - https://gigobyte.github.io/purify/
ISC License
1.5k stars 58 forks source link

Incorrect typing of EitherAsync.map #615

Closed LouisBoucquet closed 1 year ago

LouisBoucquet commented 1 year ago

I've found an issue with the typing of EitherAsync.map. When returning a Promise<T> in de the map function typescript tells us that the new type is EitherAsync<Promise<T>>. But in actuality the type should be EitherAsync<T>, the Promise<T> gets unwrapped to T just like with a regular promise.then(...).

Example:

EitherAsync(() => Promise.resolve(null))
    .map(() => Promise.resolve('yeet'))
    .map(value => {
        // Typescript says this is a `Promise` but the promise actually gets unwrapped, so it is a `string` instead
        console.log(typeof value);
    });

Current incorrect typing of map:

map<R2>(f: (value: R) => R2): EitherAsync<L, R2>;

Proposed correct typing of map:

map<R2>(f: (value: R) => R2): EitherAsync<L, R2 extends Promise<infer R2Unwrapped> ? R2Unwrapped : R2>;
gigobyte commented 1 year ago

Related runtime issue: https://github.com/gigobyte/purify/issues/525

gigobyte commented 1 year ago

Fixed in v1.3.2