Skip to content

Instantly share code, notes, and snippets.

@minajevs
Created March 13, 2019 08:03
Show Gist options
  • Save minajevs/af6c11fabacc4b0bb3566f325b4bc507 to your computer and use it in GitHub Desktop.
Save minajevs/af6c11fabacc4b0bb3566f325b4bc507 to your computer and use it in GitHub Desktop.
import { ThunkAction, ThunkDispatch } from 'redux-thunk'
import { AnyAction, Action, Dispatch } from 'redux'
export type PayloadCallback<State, Actions extends AnyAction, Payload> = (
dispatch: ThunkDispatch<State, undefined, Actions>,
payload: Payload /*, getState: () => State */
) => Promise<Action>
export type Callback<State, Actions extends AnyAction> = (
dispatch: ThunkDispatch<State, undefined, Actions> /*, getState: () => State */
) => Promise<Action>
type UnionCallback<State, Actions extends AnyAction, Payload> =
Payload extends undefined
? Callback<State, Actions>
: PayloadCallback<State, Actions, Payload>
// We need that so that ThunkDispatch could dispatch other state thunks
type AnyState = {}
// HACK to implement optional function argument.
// Read more: https://github.com/Microsoft/TypeScript/issues/12400
type OptionalSpread<T> =
T extends undefined
? []
: [T]
function isPayload<Payload = undefined>(
payload: Payload
): payload is Payload {
return typeof payload !== 'undefined'
}
export function createThunk<State extends AnyState = {}, Actions extends AnyAction = AnyAction, Payload = undefined>(
callback: UnionCallback<State, Actions, Payload>
): (...args: OptionalSpread<Payload>) => ThunkAction<Promise<Action>, AnyState, undefined, Actions> {
return (...args: OptionalSpread<Payload>) => {
const payload = args[0]
if (isPayload(payload))
return (dispatch: Dispatch | ThunkDispatch<AnyState, undefined, Actions>, getState) =>
// @ts-ignore
(callback as PayloadCallback<AnyState, Actions, Payload>)(dispatch, payload /*, getState */)
else
return (dispatch: Dispatch | ThunkDispatch<AnyState, undefined, Actions>, getState) =>
(callback as Callback<AnyState, Actions>)(dispatch /*, getState */)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment