Skip to content

Instantly share code, notes, and snippets.

@ChillyBwoy
Created December 6, 2017 13:17
Show Gist options
  • Save ChillyBwoy/f658848d354262f0112126d40b3b188e to your computer and use it in GitHub Desktop.
Save ChillyBwoy/f658848d354262f0112126d40b3b188e to your computer and use it in GitHub Desktop.
Thunk-like middleware for redux and TypeScript 2.6 (without extra argument)
import * as Redux from "redux";
import { MiddlewareAction } from "./redux-middleware";
export interface StateType {
foo: string;
bar: number;
}
export type ActionType
= {
type: "@app/FOO";
foo: string;
}
| {
type: "@app/BAR";
bar: number;
};
export function actionForFoo(foo: string): MiddlewareAction<StateType, ActionType> {
return {
foo,
type: "@app/FOO",
};
}
export function actionForBar(bar: boolean): MiddlewareAction<StateType, ActionType, number> {
return (dispatch, getState) => {
dispatch({
bar: Math.random(),
type: "@app/BAR",
});
return 42;
};
}
const initialState: StateType = {
foo: "",
bar: 0,
};
const reducer = (state: StateType = initialState, action: ActionType): StateType => {
switch (action.type) {
case "@app/FOO": {
return {
...state,
foo: action.foo
};
}
case "@app/BAR": {
return {
...state,
bar: action.bar
};
}
default: {
return state;
}
}
};
const store = Redux.createStore(
reducer,
Redux.applyMiddleware(reduxDispatchMiddleware));
/**
* Current implementation of [redux-thunk](https://github.com/gaearon/redux-thunk)
* is completely broken, so here is some experimental middleware, which can
* handle TypeScript 2.6
*/
import * as Redux from "redux";
export type MiddlewareAPI<S> = {
dispatch: Redux.Dispatch<S>;
getState: () => S;
};
export type MiddlewareAction<S, A extends Redux.Action, R = void>
= ((dispatch: Redux.Dispatch<S>, getState: () => S) => R)
| A;
declare module "redux" {
export interface Dispatch<S> {
<A extends MiddlewareAction<S, any>>(action: A): A;
}
}
export function reduxDispatchMiddleware<S>({ dispatch, getState }: MiddlewareAPI<S>) {
return (next: Redux.Dispatch<S>) => (action: MiddlewareAction<S, any>) => {
if (typeof action === "function") {
return action(dispatch, getState);
}
return next(action);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment