Skip to content

Commit

Permalink
add typings for createReducer
Browse files Browse the repository at this point in the history
  • Loading branch information
mtinner authored Oct 23, 2019
1 parent 0d64561 commit 2b30566
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions src/createReducer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
import { useCallback, useRef, useState } from 'react';
import useUpdateEffect from './useUpdateEffect';

function composeMiddleware(chain) {
return (context, dispatch) => {
type Dispatch<Action> = (action: Action) => void;

type Store<Action, State> = {
getState: () => State;
dispatch: Dispatch<Action>;
};

type Middleware<Action, State> = (
store: Store<Action, State>
) => (next: Dispatch<Action>) => (action: Action) => void;

function composeMiddleware<Action, State>(chain: Middleware<Action, State>[]) {
return (context: Store<Action, State>, dispatch: Dispatch<Action>) => {
return chain.reduceRight((res, middleware) => {
return middleware(context)(res);
}, dispatch);
};
}

const createReducer = (...middlewares) => {
const composedMiddleware = composeMiddleware(middlewares);
const createReducer = <Action, State>(
...middlewares: Middleware<Action, State>[]
) => {
const composedMiddleware = composeMiddleware<Action, State>(middlewares);

return (reducer, initialState, initializer = value => value) => {
return (
reducer: (state: State, action: Action) => State,
initialState: State,
initializer = (value: State) => value
): [State, Dispatch<Action>] => {
const ref = useRef(initializer(initialState));
const [, setState] = useState(ref.current);

Expand All @@ -25,11 +42,11 @@ const createReducer = (...middlewares) => {
[reducer]
);

const dispatchRef = useRef(
const dispatchRef: { current: Dispatch<Action> } = useRef(
composedMiddleware(
{
getState: () => ref.current,
dispatch: (...args) => dispatchRef.current(...args),
dispatch: (...args: [Action]) => dispatchRef.current(...args)
},
dispatch
)
Expand All @@ -39,7 +56,7 @@ const createReducer = (...middlewares) => {
dispatchRef.current = composedMiddleware(
{
getState: () => ref.current,
dispatch: (...args) => dispatchRef.current(...args),
dispatch: (...args: [Action]) => dispatchRef.current(...args)
},
dispatch
);
Expand Down

0 comments on commit 2b30566

Please sign in to comment.