import { Reducer , useMemo , useReducer } from 'react' ; type Action = { type : string ; payload ? : any ; } ; type CreateMethods < M , T > = ( state : T ) => { [ P in keyof M ] : ( payload ? : any ) => T ; } ; type WrappedMethods < M > = { [ P in keyof M ] : ( ... payload : any ) => void ; } ; const useMethods = < M , T > ( createMethods , initialState ) : [ T , WrappedMethods < M > ] => { const reducer = useMemo < Reducer < T , Action > > ( ( ) => ( reducerState , action ) => { return createMethods ( reducerState ) [ action . type ] ( ... action . payload ) ; } , [ createMethods ] ) ; const [ state , dispatch ] = useReducer < Reducer < T , Action > > ( reducer , initialState ) ; const wrappedMethods = useMemo ( ( ) => { const actionTypes = Object . keys ( createMethods ( initialState ) ) ; return actionTypes . reduce ( ( acc , type ) => { acc [ type ] = ( ... payload ) => dispatch ( { type , payload } ) ; return acc ; } , { } as WrappedMethods < M > ) ; } , [ createMethods , initialState ] ) ; return [ state , wrappedMethods ] ; } ; export default useMethods ;