From 2b30566ad3a25d0e4267ac1050487b20073a1f0a Mon Sep 17 00:00:00 2001 From: Marcel Tinner Date: Wed, 23 Oct 2019 15:13:22 +0200 Subject: [PATCH 1/2] add typings for createReducer --- src/createReducer.ts | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/createReducer.ts b/src/createReducer.ts index 781900f45a..cee9ba867d 100644 --- a/src/createReducer.ts +++ b/src/createReducer.ts @@ -1,18 +1,35 @@ import { useCallback, useRef, useState } from 'react'; import useUpdateEffect from './useUpdateEffect'; -function composeMiddleware(chain) { - return (context, dispatch) => { +type Dispatch = (action: Action) => void; + +type Store = { + getState: () => State; + dispatch: Dispatch; +}; + +type Middleware = ( + store: Store +) => (next: Dispatch) => (action: Action) => void; + +function composeMiddleware(chain: Middleware[]) { + return (context: Store, dispatch: Dispatch) => { return chain.reduceRight((res, middleware) => { return middleware(context)(res); }, dispatch); }; } -const createReducer = (...middlewares) => { - const composedMiddleware = composeMiddleware(middlewares); +const createReducer = ( + ...middlewares: Middleware[] +) => { + const composedMiddleware = composeMiddleware(middlewares); - return (reducer, initialState, initializer = value => value) => { + return ( + reducer: (state: State, action: Action) => State, + initialState: State, + initializer = (value: State) => value + ): [State, Dispatch] => { const ref = useRef(initializer(initialState)); const [, setState] = useState(ref.current); @@ -25,11 +42,11 @@ const createReducer = (...middlewares) => { [reducer] ); - const dispatchRef = useRef( + const dispatchRef: { current: Dispatch } = useRef( composedMiddleware( { getState: () => ref.current, - dispatch: (...args) => dispatchRef.current(...args), + dispatch: (...args: [Action]) => dispatchRef.current(...args) }, dispatch ) @@ -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 ); From 0c20fb98fa3b93d2674a21a4b63e191af64e8bd1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 24 Oct 2019 07:06:54 +0200 Subject: [PATCH 2/2] change dispatchRef to mutableRefObject --- src/createReducer.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/createReducer.ts b/src/createReducer.ts index cee9ba867d..7cece51cbc 100644 --- a/src/createReducer.ts +++ b/src/createReducer.ts @@ -1,18 +1,16 @@ -import { useCallback, useRef, useState } from 'react'; +import { MutableRefObject, useCallback, useRef, useState } from 'react'; import useUpdateEffect from './useUpdateEffect'; type Dispatch = (action: Action) => void; -type Store = { +interface Store { getState: () => State; dispatch: Dispatch; -}; +} -type Middleware = ( - store: Store -) => (next: Dispatch) => (action: Action) => void; +type Middleware = (store: Store) => (next: Dispatch) => (action: Action) => void; -function composeMiddleware(chain: Middleware[]) { +function composeMiddleware(chain: Array>) { return (context: Store, dispatch: Dispatch) => { return chain.reduceRight((res, middleware) => { return middleware(context)(res); @@ -20,9 +18,7 @@ function composeMiddleware(chain: Middleware[]) { }; } -const createReducer = ( - ...middlewares: Middleware[] -) => { +const createReducer = (...middlewares: Array>) => { const composedMiddleware = composeMiddleware(middlewares); return ( @@ -42,11 +38,11 @@ const createReducer = ( [reducer] ); - const dispatchRef: { current: Dispatch } = useRef( + const dispatchRef: MutableRefObject> = useRef( composedMiddleware( { getState: () => ref.current, - dispatch: (...args: [Action]) => dispatchRef.current(...args) + dispatch: (...args: [Action]) => dispatchRef.current(...args), }, dispatch ) @@ -56,7 +52,7 @@ const createReducer = ( dispatchRef.current = composedMiddleware( { getState: () => ref.current, - dispatch: (...args: [Action]) => dispatchRef.current(...args) + dispatch: (...args: [Action]) => dispatchRef.current(...args), }, dispatch );