Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide more informative names for TypeScript type params #243

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 89 additions & 23 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,113 @@ import {
ActionCreatorsMapObject,
AnyAction,
Dispatch,
Middleware,
} from 'redux';
Middleware
} from "redux";

export interface ThunkDispatch<S, E, A extends Action> {
<R>(thunkAction: ThunkAction<R, S, E, A>): R;
<T extends A>(action: T): T;
/**
* The dispatch method as modified by React-Thunk; overloaded so that you can
* dispatch:
* - standard (object) actions: `dispatch()` returns the action itself
* - thunk actions: `dispatch()` returns the thunk's return value
*
* @template TState The redux state
* @template TExtraThunkArg The extra argument passed to the inner function of
* thunks (if specified when setting up the Thunk middleware)
* @template TBasicAction The (non-thunk) actions that can be dispatched.
*/
export interface ThunkDispatch<
TState,
TExtraThunkArg,
TBasicAction extends Action
> {
<TReturnType>(
thunkAction: ThunkAction<TReturnType, TState, TExtraThunkArg, TBasicAction>
): TReturnType;
<A extends TBasicAction>(action: A): A;
}

export type ThunkAction<R, S, E, A extends Action> = (
dispatch: ThunkDispatch<S, E, A>,
getState: () => S,
extraArgument: E
) => R;
/**
* A "thunk" action (a callback function that can be dispatched to the Redux
* store.)
*
* Also known as the "thunk inner function", when used with the typical pattern
* of an action creator function that returns a thunk action.
*
* @template TReturnType The return type of the thunk's inner function
* @template TState The redux state
* @template TExtraThunkARg Optional extra argument passed to the inner function
* (if specified when setting up the Thunk middleware)
* @template TBasicAction The (non-thunk) actions that can be dispatched.
*/
export type ThunkAction<
TReturnType,
TState,
TExtraThunkArg,
TBasicAction extends Action
> = (
dispatch: ThunkDispatch<TState, TExtraThunkArg, TBasicAction>,
getState: () => TState,
extraArgument: TExtraThunkArg
) => TReturnType;

/**
* Takes a ThunkAction and returns a function signature which matches how it would appear when processed using
* bindActionCreators
* A generic type that takes a thunk action creator and returns a function
* signature which matches how it would appear after being processed using
* bindActionCreators(): a function that takes the arguments of the outer
* function, and returns the return type of the inner "thunk" function.
*
* @template T ThunkAction to be wrapped
* @template TActionCreator Thunk action creator to be wrapped
*/
export type ThunkActionDispatch<T extends (...args: any[]) => ThunkAction<any, any, any, any>> = (...args: Parameters<T>)
=> ReturnType<ReturnType<T>>;
export type ThunkActionDispatch<
TActionCreator extends (...args: any[]) => ThunkAction<any, any, any, any>
> = (
...args: Parameters<TActionCreator>
) => ReturnType<ReturnType<TActionCreator>>;

export type ThunkMiddleware<S = {}, A extends Action = AnyAction, E = undefined> = Middleware<ThunkDispatch<S, E, A>, S, ThunkDispatch<S, E, A>>;
/**
* @template TState The redux state
* @template TBasicAction The (non-thunk) actions that can be dispatched
* @template TExtraThunkArg An optional extra argument to pass to a thunk's
* inner function. (Only used if you call `thunk.withExtraArgument()`)
*/
export type ThunkMiddleware<
TState = {},
TBasicAction extends Action = AnyAction,
TExtraThunkARg = undefined
> = Middleware<
ThunkDispatch<TState, TExtraThunkARg, TBasicAction>,
TState,
ThunkDispatch<TState, TExtraThunkARg, TBasicAction>
>;

declare const thunk: ThunkMiddleware & {
withExtraArgument<E>(extraArgument: E): ThunkMiddleware<{}, AnyAction, E>
}
withExtraArgument<TExtraThunkArg>(
extraArgument: TExtraThunkArg
): ThunkMiddleware<{}, AnyAction, TExtraThunkArg>;
};

export default thunk;

/**
* Redux behaviour changed by middleware, so overloads here
*/
declare module 'redux' {
declare module "redux" {
/**
* Overload for bindActionCreators redux function, returns expects responses
* from thunk actions
*/
function bindActionCreators<M extends ActionCreatorsMapObject<any>>(
actionCreators: M,
dispatch: Dispatch,
): { [N in keyof M]: ReturnType<M[N]> extends ThunkAction<any, any, any, any> ? (...args: Parameters<M[N]>) => ReturnType<ReturnType<M[N]>> : M[N] }
function bindActionCreators<
TActionCreators extends ActionCreatorsMapObject<any>
>(
actionCreators: TActionCreators,
dispatch: Dispatch
): {
[TActionCreatorName in keyof TActionCreators]: ReturnType<
TActionCreators[TActionCreatorName]
> extends ThunkAction<any, any, any, any>
? (
...args: Parameters<TActionCreators[TActionCreatorName]>
) => ReturnType<ReturnType<TActionCreators[TActionCreatorName]>>
: TActionCreators[TActionCreatorName]
};
}