import type { Action , AnyAction } from 'redux' ; import type { CaseReducer , CaseReducers , ActionMatcher , ActionMatcherDescriptionCollection , } from './createReducer' ; export interface TypedActionCreator < Type extends string > { ( ... args ) : Action < Type > ; type : Type ; } public export interface ActionReducerMapBuilder < State > { remarks param actionCreator param reducer addCase < ActionCreator extends TypedActionCreator < string > > ( actionCreator , reducer ) : ActionReducerMapBuilder < State > ; remarks param actionCreator param reducer addCase < Type extends string , A extends Action < Type > > ( type , reducer ) : ActionReducerMapBuilder < State > ; remarks param matcher param reducer example addMatcher < A extends AnyAction > ( matcher , reducer ) : Omit < ActionReducerMapBuilder < State > , 'addCase' > ; param reducer example addDefaultCase ( reducer ) : { } ; } export function executeReducerBuilderCallback < S > ( builderCallback ) { const actionsMap = { } ; const actionMatchers = [ ] ; let defaultCaseReducer ; const builder = { addCase ( typeOrActionCreator , reducer ) { if ( process . env . NODE_ENV !== 'production' ) { if ( actionMatchers . length > 0 ) { throw new Error ( '`builder.addCase` should only be called before calling `builder.addMatcher`' ) ; } if ( defaultCaseReducer ) { throw new Error ( '`builder.addCase` should only be called before calling `builder.addDefaultCase`' ) ; } } const type = typeof typeOrActionCreator === 'string' ? typeOrActionCreator : typeOrActionCreator . type ; if ( type in actionsMap ) { throw new Error ( 'addCase cannot be called with two reducers for the same action type' ) ; } actionsMap [ type ] = reducer ; return builder ; } , addMatcher < A extends AnyAction > ( matcher , reducer ) { if ( process . env . NODE_ENV !== 'production' ) { if ( defaultCaseReducer ) { throw new Error ( '`builder.addMatcher` should only be called before calling `builder.addDefaultCase`' ) ; } } actionMatchers . push ( { matcher , reducer } ) ; return builder ; } , addDefaultCase ( reducer ) { if ( process . env . NODE_ENV !== 'production' ) { if ( defaultCaseReducer ) { throw new Error ( '`builder.addDefaultCase` can only be called once' ) ; } } defaultCaseReducer = reducer ; return builder ; } , } ; builderCallback ( builder ) ; return [ actionsMap , actionMatchers , defaultCaseReducer ] ; }