import { Reducer } from 'redux';
import { PayloadAction, PayloadActionCreator, PrepareAction, ActionCreatorWithoutPayload, ActionCreatorWithPreparedPayload } from './createAction';
import { CaseReducers, CaseReducer } from './createReducer';
/**
 * An action creator atttached to a slice.
 *
 * @deprecated please use PayloadActionCreator directly
 */
export declare type SliceActionCreator<P> = PayloadActionCreator<P>;
export interface Slice<State = any, CaseReducers extends SliceCaseReducerDefinitions<State, PayloadActions> = {
    [key: string]: any;
}> {
    /**
     * The slice name.
     */
    name: string;
    /**
     * The slice's reducer.
     */
    reducer: Reducer<State>;
    /**
     * Action creators for the types of actions that are handled by the slice
     * reducer.
     */
    actions: CaseReducerActions<CaseReducers>;
    caseReducers: SliceDefinedCaseReducers<CaseReducers, State>;
}
/**
 * Options for `createSlice()`.
 */
export interface CreateSliceOptions<State = any, CR extends SliceCaseReducerDefinitions<State, any> = SliceCaseReducerDefinitions<State, any>> {
    /**
     * The slice's name. Used to namespace the generated action types.
     */
    name: string;
    /**
     * The initial state to be returned by the slice reducer.
     */
    initialState: 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: CR;
    /**
     * A mapping from action types to action-type-specific *case reducer*
     * functions. These reducers should have existing action types used
     * as the keys, and action creators will _not_ be generated.
     */
    extraReducers?: CaseReducers<NoInfer<State>, any>;
}
declare type PayloadActions<Types extends keyof any = string> = Record<Types, PayloadAction>;
declare type CaseReducerWithPrepare<State, Action extends PayloadAction> = {
    reducer: CaseReducer<State, Action>;
    prepare: PrepareAction<Action['payload']>;
};
declare type SliceCaseReducerDefinitions<State, PA extends PayloadActions> = {
    [ActionType in keyof PA]: CaseReducer<State, PA[ActionType]> | CaseReducerWithPrepare<State, PA[ActionType]>;
};
declare type IfIsReducerFunctionWithoutAction<R, True, False = never> = R extends (state: any) => any ? True : False;
declare type IfIsCaseReducerWithPrepare<R, True, False = never> = R extends {
    prepare: Function;
} ? True : False;
declare type PayloadForReducer<R> = R extends (state: any, action: PayloadAction<infer P>) => any ? P : void;
declare type PrepareActionForReducer<R> = R extends {
    prepare: infer Prepare;
} ? Prepare : never;
declare type ActionForReducer<R, S> = R extends (state: S, action: PayloadAction<infer P>) => S ? PayloadAction<P> : R extends {
    reducer(state: any, action: PayloadAction<infer P>): any;
} ? PayloadAction<P> : unknown;
declare type CaseReducerActions<CaseReducers extends SliceCaseReducerDefinitions<any, any>> = {
    [Type in keyof CaseReducers]: IfIsCaseReducerWithPrepare<CaseReducers[Type], ActionCreatorWithPreparedPayload<PrepareActionForReducer<CaseReducers[Type]>>, IfIsReducerFunctionWithoutAction<CaseReducers[Type], ActionCreatorWithoutPayload, PayloadActionCreator<PayloadForReducer<CaseReducers[Type]>>>>;
};
declare type SliceDefinedCaseReducers<CaseReducers extends SliceCaseReducerDefinitions<any, any>, State = any> = {
    [Type in keyof CaseReducers]: CaseReducer<State, ActionForReducer<CaseReducers[Type], State>>;
};
declare type NoInfer<T> = [T][T extends any ? 0 : never];
declare type SliceCaseReducersCheck<S, ACR> = {
    [P in keyof ACR]: ACR[P] extends {
        reducer(s: S, action?: {
            payload: infer O;
        }): any;
    } ? {
        prepare(...a: never[]): {
            payload: O;
        };
    } : {};
};
declare type RestrictCaseReducerDefinitionsToMatchReducerAndPrepare<S, CR extends SliceCaseReducerDefinitions<S, any>> = {
    reducers: SliceCaseReducersCheck<S, NoInfer<CR>>;
};
/**
 * A function that accepts an initial state, an object full of reducer
 * functions, and a "slice name", and automatically generates
 * action creators and action types that correspond to the
 * reducers and state.
 *
 * The `reducer` argument is passed to `createReducer()`.
 */
export declare function createSlice<State, CaseReducers extends SliceCaseReducerDefinitions<State, any>>(options: CreateSliceOptions<State, CaseReducers> & RestrictCaseReducerDefinitionsToMatchReducerAndPrepare<State, CaseReducers>): Slice<State, CaseReducers>;
export {};
