gigobyte / purify

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

Adding a new type for representing the "state" of an async operation #658

Closed brmenchl closed 10 months ago

brmenchl commented 10 months ago

At my company, we wanted to use Either to represent operations with potential exceptional states, but a lot of these operations are the result of async operations which return a non-Promise representation of the operation state

e.g. a react hook returning

{ isLoading: true, isError: false, data: undefined, error: undefined } |
{ isLoading: false, isError: false, data: T, error: undefined } |
{ isLoading: false, isError: true, data: undefined, error: E }

(I guess you could call this a representation of async state)

This representation or something like it shows up quite a lot, at least in react development scenarios (react-query, swr, apollo client, common redux patterns), and the addition of the isLoading flag makes Either difficult to use or unusable.

First we tried using Maybe<Either<L, R>>, but having to chain flatMaps on many calls was cumbersome especially for folks who were newer to functional programming.

We decided to create a type based heavily off of purify's Either but adding a Loading state, creating essentially: type AsyncResult = Left<L, R> | Right<R, L> | Loading<L, R> (we followed the same pattern as purify source code, so the implementation actually uses classes and interfaces)

Is this something that would make sense to add to purify as a whole? I haven't seen a type like this show up in most functional programming libraries. However, ts-belt is considering adding a sum type does cover a very similar use case: AsyncDataResult: https://github.com/mobily/ts-belt/issues/51

gigobyte commented 10 months ago

In the case of react development, I would recommend using a proven library like react-query that handles not only the loading state but caching, management (refetching, invalidation) and a lot of other useful things. Even if purify provided such a data type it would always be inferior to specialized libraries.

brmenchl commented 10 months ago

Our use case is actually for react-query coincidentally. React-queries types don't work super well for aggregating the results of multiple async operations without a lot of extra typescript boilerplate and conditional logic. It makes sense though, I'll close this.