Created
September 15, 2022 06:09
-
-
Save stylemistake/d151e26de021a3afca33125abb1c1047 to your computer and use it in GitHub Desktop.
Loadable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum LoadableStates { | |
Initial = 'initial', | |
Loading = 'loading', | |
Error = 'error', | |
Value = 'value', | |
} | |
type LoadableInitial = Loadable & { | |
readonly state: LoadableStates.Initial; | |
}; | |
type LoadableLoading = Loadable & { | |
readonly state: LoadableStates.Loading; | |
}; | |
type LoadableValue<T = any, E = any> = Loadable<T, E> & { | |
readonly state: LoadableStates.Value; | |
readonly value: T; | |
}; | |
type LoadableError<T = any, E = any> = Loadable<T, E> & { | |
readonly state: LoadableStates.Error; | |
readonly value: E; | |
}; | |
export class Loadable<T = any, E = any> { | |
/** Represents a value that has not been initialized. */ | |
static initial = new Loadable(LoadableStates.Initial) as LoadableInitial; | |
/** Represents a state of loading. */ | |
static loading = new Loadable(LoadableStates.Loading) as LoadableLoading; | |
/** Represents a loading error. Error object is optional. */ | |
static error(): LoadableError; | |
static error<E>(error: E): LoadableError<any, E>; | |
static error<E>(error?: E) { | |
return new Loadable<any, E>(LoadableStates.Error, error); | |
} | |
/** Represents a successfully loaded value. Value itself is optional, though. */ | |
static value(): LoadableValue; | |
static value<T>(value: T): LoadableValue<T>; | |
static value<T>(value?: T) { | |
return new Loadable<T>(LoadableStates.Value, value); | |
} | |
readonly state; | |
readonly value?: T; | |
readonly error?: E; | |
private constructor(state: LoadableStates, contents?: any) { | |
// Need to explicitly set the values in the constructor due to bugs in the TS compiler in storybook | |
this.state = state; | |
if (state === LoadableStates.Value) { | |
this.value = contents; | |
} | |
else if (state === LoadableStates.Error) { | |
this.error = contents; | |
} | |
} | |
isInitial(): this is LoadableInitial { | |
return this.state === LoadableStates.Initial; | |
} | |
isLoading(): this is LoadableLoading { | |
return this.state === LoadableStates.Loading; | |
} | |
isError(): this is LoadableError<T, E> { | |
return this.state === LoadableStates.Error; | |
} | |
isValue(): this is LoadableValue<T, E> { | |
return this.state === LoadableStates.Value; | |
} | |
isDone(): boolean { | |
return this.isValue() || this.isError(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment