Skip to content

Commit

Permalink
feat: add typings for createReducer
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich authored Oct 31, 2019
2 parents 0e628e2 + 0c20fb9 commit f1cf036
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions src/createReducer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import { useCallback, useRef, useState } from 'react';
import { MutableRefObject, useCallback, useRef, useState } from 'react';
import useUpdateEffect from './useUpdateEffect';

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

interface 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: Array<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: Array<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 +38,11 @@ const createReducer = (...middlewares) => {
[reducer]
);

const dispatchRef = useRef(
const dispatchRef: MutableRefObject<Dispatch<Action>> = useRef(
composedMiddleware(
{
getState: () => ref.current,
dispatch: (...args) => dispatchRef.current(...args),
dispatch: (...args: [Action]) => dispatchRef.current(...args),
},
dispatch
)
Expand All @@ -39,7 +52,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 f1cf036

Please sign in to comment.