Skip to content

Commit

Permalink
Provide more informative names for TypeScript type params (#243)
Browse files Browse the repository at this point in the history
... and expanding the docblocks in the type definition file.
  • Loading branch information
agwells authored and timdorr committed Apr 12, 2019
1 parent 9eb31ec commit 0e60b62
Showing 1 changed file with 89 additions and 23 deletions.
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]
};
}

0 comments on commit 0e60b62

Please sign in to comment.