Created
February 9, 2019 02:02
-
-
Save ferdaber/eb4bd09ad88f65fa89ac7f7ff92fe341 to your computer and use it in GitHub Desktop.
strongly-typed-redux-2
This file contains hidden or 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
| type State = any | |
| /** | |
| * General action type | |
| */ | |
| export type Action<TType extends string = string, TPayload = any> = TPayload extends undefined | |
| ? { | |
| type: TType | |
| } | |
| : { | |
| type: TType | |
| payload: TPayload | |
| } | |
| /** | |
| * A type of action that is actually dispatched after the promise middleware | |
| * modifies it if it has a promise-based payload | |
| */ | |
| export interface PromiseAction<TAction extends Action<any, Promise<any>>> { | |
| status: string | |
| payload: any | |
| type: TAction['type'] | |
| promise: TAction['payload'] | |
| } | |
| /** | |
| * The type of a dispatched action when it has a promise as a payload | |
| * This one is immediately dispatched after going through the middleware | |
| */ | |
| export interface PendingPromiseAction<TAction extends Action<any, Promise<any>>> | |
| extends PromiseAction<TAction> { | |
| status: 'pending' | |
| payload: TAction['payload'] | |
| } | |
| /** | |
| * The type of a dispatched action when it has a promise as a payload | |
| * This one is dispatched when the promise is fulfilled | |
| */ | |
| export interface FulfilledPromiseAction<TAction extends Action<any, Promise<any>>> | |
| extends PromiseAction<TAction> { | |
| status: 'fulfilled' | |
| payload: PromiseValue<TAction['payload']> | |
| } | |
| /** | |
| * The type of a dispatched action when it has a promise as a payload | |
| * This one is dispatched when the promise is rejected | |
| */ | |
| export interface RejectedPromiseAction<TAction extends Action<any, Promise<any>>> | |
| extends PromiseAction<TAction> { | |
| status: 'rejected' | |
| payload: Error | |
| } | |
| /** | |
| * Types of actions created from an action creator, mainly if it's a promise-based | |
| * action it can potentially dispatch three actions based on how the promise resolves | |
| */ | |
| export type PossibleActions<TActionCreator extends ActionCreator> = TActionCreator extends any | |
| ? ReturnType<TActionCreator> extends { payload: Promise<any> } | |
| ? | |
| | PendingPromiseAction<ReturnType<TActionCreator>> | |
| | FulfilledPromiseAction<ReturnType<TActionCreator>> | |
| | RejectedPromiseAction<ReturnType<TActionCreator>> | |
| : ReturnType<TActionCreator> | |
| : never | |
| /** | |
| * General action creator type | |
| */ | |
| export interface ActionCreator< | |
| TType extends string = string, | |
| TPayload = any, | |
| TArgs extends any[] = [] | |
| > { | |
| (...args: TArgs): Action<TType, TPayload> | |
| type: TType | |
| toString(): TType | |
| } | |
| /** | |
| * Given an actual action object, resolves the return type | |
| * when this action object is dispatched, using thunk and promise middlewares | |
| */ | |
| export type DispatchedAction<TAction> = TAction extends { type: infer TType } | |
| ? TType extends string | |
| ? TAction extends { payload: Promise<any> } | |
| ? PendingPromiseAction<TAction> | |
| : TAction | |
| : never | |
| : TAction extends Thunk<infer TReturn> | |
| ? TReturn | |
| : never | |
| /** | |
| * Call signature of the dispatch function, which is more restrictive than the | |
| * DispatchedAction type, but essentially the same, in function form | |
| */ | |
| export interface Dispatch<TState = State> { | |
| <TAction extends Action>(action: TAction): DispatchedAction<TAction> | |
| <TReturn>(thunk: (dispatch: Dispatch<TState>, getState: () => TState) => TReturn): TReturn | |
| } | |
| /** | |
| * Call signature of a thunk, which is passed the dispatch and getState APIs | |
| */ | |
| export interface Thunk<TReturn, TState = State> { | |
| (dispatch: Dispatch<TState>, getState: () => TState): TReturn | |
| } | |
| /** | |
| * A reducer based off of a state slice and an action creator, it can mutate the state | |
| * because of the outer Immer wrapper | |
| */ | |
| export interface Reducer<TState, TActionCreator extends ActionCreator> { | |
| (state: TState, action: PossibleActions<TActionCreator>): void | TState | |
| type: TActionCreator['type'] | |
| } | |
| export interface Middleware<TState = State> { | |
| ( | |
| store: { | |
| dispatch: Dispatch<TState> | |
| getState(): TState | |
| } | |
| ): (next: (action: any) => void) => (action: any) => void | |
| } | |
| export declare function mapDispatchToProps<A extends Records<string, () => any>>(actionCreators: A, dispatch: Dispatch): { | |
| [K in keyof A]: A[K] extends (...args: infer TArgs) => infer TAction ? (...args: TArgs) => DispatchedAction<TAction> : A[K] | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@brieb