Skip to content

Instantly share code, notes, and snippets.

@akatakritos
Last active September 27, 2021 19:09
Show Gist options
  • Save akatakritos/ff0d5c3454c14bdd2afa17871abf0e2c to your computer and use it in GitHub Desktop.
Save akatakritos/ff0d5c3454c14bdd2afa17871abf0e2c to your computer and use it in GitHub Desktop.
Pattern for tracking loading states. Demo of typescript discriminated union
export type LoadingStatus = 'idle' | 'loading' | 'fulfilled' | 'rejected';
export type LoadingState<T, E = Error> =
| { state: 'idle' }
| { state: 'loading' }
| { state: 'fulfilled'; data: T }
| { state: 'rejected'; error: E };
export const LoadingStates = {
idle<T, E = Error>() {
return { state: 'idle' } as LoadingState<T, E>;
},
pending<T, E = Error>() {
return { state: 'loading' } as LoadingState<T, E>;
},
fulfilled<T, E = Error>(data: T) {
return { state: 'fulfilled', data } as LoadingState<T, E>;
},
rejected<T, E = Error>(error: E) {
return { state: 'rejected', error } as LoadingState<T, E>;
},
map<TSource, TOutput, E = Error>(source: LoadingState<TSource, E>, f: (a: TSource) => TOutput): LoadingState<TOutput, E> {
if (source.state === 'fulfilled') {
return { state: 'fulfilled', data: f(source.data) };
} else {
return source as LoadingState<TOutput, E>;
}
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment