import type { AnyAction , Reducer } from 'redux' ; import { createNextState } from '.' ; import type { ActionCreatorWithoutPayload , PayloadAction , PayloadActionCreator , PrepareAction , _ActionCreatorWithPreparedPayload , } from './createAction' ; import { createAction } from './createAction' ; import type { CaseReducer , CaseReducers , ReducerWithInitialState , } from './createReducer' ; import { createReducer , NotFunction } from './createReducer' ; import type { ActionReducerMapBuilder } from './mapBuilders' ; import { executeReducerBuilderCallback } from './mapBuilders' ; import type { NoInfer } from './tsHelpers' ; deprecated public export type SliceActionCreator < P > = PayloadActionCreator < P > ; public export interface Slice < State = any , CaseReducers extends SliceCaseReducers < State > = SliceCaseReducers < State > , Name extends string = string > { /**
     * The slice name.
     */ name : Name ; /**
     * The slice's reducer.
     */ reducer : Reducer < State > ; /**
     * Action creators for the types of actions that are handled by the slice
     * reducer.
     */ actions : CaseReducerActions < CaseReducers > ; /**
     * The individual case reducer functions that were passed in the `reducers` parameter.
     * This enables reuse and testing if they were defined inline when calling `createSlice`.
     */ caseReducers : SliceDefinedCaseReducers < CaseReducers > ; /**
     * Provides access to the initial state value given to the slice.
     * If a lazy state initializer was provided, it will be called and a fresh value returned.
     */ getInitialState : ( ) => State ; } public export interface CreateSliceOptions < State = any , CR extends SliceCaseReducers < State > = SliceCaseReducers < State > , Name extends string = string > { /**
     * The slice's name. Used to namespace the generated action types.
     */ name : Name ; /**
     * The initial state that should be used when the reducer is called the first time. This may also be a "lazy initializer" function, which should return an initial state value when called. This will be used whenever the reducer is called with `undefined` as its state value, and is primarily useful for cases like reading initial state from `localStorage`.
     */ initialState : State | ( ( ) => State ) ; /**
     * A mapping from action types to action-type-specific *case reducer*
     * functions. For every action type, a matching action creator will be
     * generated using `createAction()`.
     */ reducers : ValidateSliceCaseReducers < State , CR > ; example extraReducers ? : CaseReducers < NoInfer < State > , any > | ( ( builder : ActionReducerMapBuilder < NoInfer < State > > ) => void ) ; } public export type CaseReducerWithPrepare < State , Action extends PayloadAction > = { reducer : CaseReducer < State , Action > ; prepare : PrepareAction < Action [ 'payload' ] > ; } ; public export type SliceCaseReducers < State > = { [ K ] : CaseReducer < State , PayloadAction < any > > | CaseReducerWithPrepare < State , PayloadAction < any , string , any , any > > ; } ; public export type CaseReducerActions < CaseReducers extends SliceCaseReducers < any > > = { [ Type in keyof CaseReducers ] : CaseReducers [ Type ] extends { prepare : any ; } ? ActionCreatorForCaseReducerWithPrepare < CaseReducers [ Type ] > : ActionCreatorForCaseReducer < CaseReducers [ Type ] > ; } ; internal type ActionCreatorForCaseReducerWithPrepare < CR extends { prepare : any ; } > = _ActionCreatorWithPreparedPayload < CR [ 'prepare' ] , string > ; internal type ActionCreatorForCaseReducer < CR > = CR extends ( state : any , action : infer Action ) => any ? Action extends { payload : infer P ; } ? PayloadActionCreator < P > : ActionCreatorWithoutPayload : ActionCreatorWithoutPayload ; internal type SliceDefinedCaseReducers < CaseReducers extends SliceCaseReducers < any > > = { [ Type in keyof CaseReducers ] : CaseReducers [ Type ] extends { reducer : infer Reducer ; } ? Reducer : CaseReducers [ Type ] ; } ; public export type ValidateSliceCaseReducers < S , ACR extends SliceCaseReducers < S > > = ACR & { [ T in keyof ACR ] : ACR [ T ] extends { reducer ( s , action ? ) : any ; } ? { prepare ( ... a ) : Omit < A , 'type' > ; } : { } ; } ; function getType ( slice , actionKey ) { return `${ slice }/${ actionKey }` ; } public export function createSlice < State , CaseReducers extends SliceCaseReducers < State > , Name extends string = string > ( options ) { const { name } = options ; if ( ! name ) { throw new Error ( '`name` is a required option for createSlice' ) ; } const initialState = typeof options . initialState == 'function' ? options . initialState : createNextState ( options . initialState , ( ) => { } ) ; const reducers = options . reducers || { } ; const reducerNames = Object . keys ( reducers ) ; const sliceCaseReducersByName = { } ; const sliceCaseReducersByType = { } ; const actionCreators = { } ; reducerNames . forEach ( ( reducerName ) => { const maybeReducerWithPrepare = reducers [ reducerName ] ; const type = getType ( name , reducerName ) ; let caseReducer ; let prepareCallback ; if ( 'reducer' in maybeReducerWithPrepare ) { caseReducer = maybeReducerWithPrepare . reducer ; prepareCallback = maybeReducerWithPrepare . prepare ; } else { caseReducer = maybeReducerWithPrepare ; } sliceCaseReducersByName [ reducerName ] = caseReducer ; sliceCaseReducersByType [ type ] = caseReducer ; actionCreators [ reducerName ] = prepareCallback ? createAction ( type , prepareCallback ) : createAction ( type ) ; } ) ; function buildReducer ( ) { const [ extraReducers = { } , actionMatchers = [ ] , defaultCaseReducer = undefined , ] = typeof options . extraReducers === 'function' ? executeReducerBuilderCallback ( options . extraReducers ) : [ options . extraReducers ] ; const finalCaseReducers = { ... extraReducers , ... sliceCaseReducersByType } ; return createReducer ( initialState , finalCaseReducers as any , actionMatchers , defaultCaseReducer ) ; } let _reducer ; return { name , reducer ( state , action ) { if ( ! _reducer ) _reducer = buildReducer ( ) ; return _reducer ( state , action ) ; } , actions : actionCreators as any , caseReducers : sliceCaseReducersByName as any , getInitialState ( ) { if ( ! _reducer ) _reducer = buildReducer ( ) ; return _reducer . getInitialState ( ) ; } , } ; }