1 | import type { Action, AnyAction } from 'redux';
|
2 | import type { CaseReducer, CaseReducers, ActionMatcherDescriptionCollection } from './createReducer';
|
3 | import type { TypeGuard } from './tsHelpers';
|
4 | export interface TypedActionCreator<Type extends string> {
|
5 | (...args: any[]): Action<Type>;
|
6 | type: Type;
|
7 | }
|
8 | /**
|
9 | * A builder for an action <-> reducer map.
|
10 | *
|
11 | * @public
|
12 | */
|
13 | export interface ActionReducerMapBuilder<State> {
|
14 | /**
|
15 | * Adds a case reducer to handle a single exact action type.
|
16 | * @remarks
|
17 | * All calls to `builder.addCase` must come before any calls to `builder.addMatcher` or `builder.addDefaultCase`.
|
18 | * @param actionCreator - Either a plain action type string, or an action creator generated by [`createAction`](./createAction) that can be used to determine the action type.
|
19 | * @param reducer - The actual case reducer function.
|
20 | */
|
21 | addCase<ActionCreator extends TypedActionCreator<string>>(actionCreator: ActionCreator, reducer: CaseReducer<State, ReturnType<ActionCreator>>): ActionReducerMapBuilder<State>;
|
22 | /**
|
23 | * Adds a case reducer to handle a single exact action type.
|
24 | * @remarks
|
25 | * All calls to `builder.addCase` must come before any calls to `builder.addMatcher` or `builder.addDefaultCase`.
|
26 | * @param actionCreator - Either a plain action type string, or an action creator generated by [`createAction`](./createAction) that can be used to determine the action type.
|
27 | * @param reducer - The actual case reducer function.
|
28 | */
|
29 | addCase<Type extends string, A extends Action<Type>>(type: Type, reducer: CaseReducer<State, A>): ActionReducerMapBuilder<State>;
|
30 | /**
|
31 | * Allows you to match your incoming actions against your own filter function instead of only the `action.type` property.
|
32 | * @remarks
|
33 | * If multiple matcher reducers match, all of them will be executed in the order
|
34 | * they were defined in - even if a case reducer already matched.
|
35 | * All calls to `builder.addMatcher` must come after any calls to `builder.addCase` and before any calls to `builder.addDefaultCase`.
|
36 | * @param matcher - A matcher function. In TypeScript, this should be a [type predicate](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates)
|
37 | * function
|
38 | * @param reducer - The actual case reducer function.
|
39 | *
|
40 | * @example
|
41 | ```ts
|
42 | import {
|
43 | createAction,
|
44 | createReducer,
|
45 | AsyncThunk,
|
46 | AnyAction,
|
47 | } from "@reduxjs/toolkit";
|
48 |
|
49 | type GenericAsyncThunk = AsyncThunk<unknown, unknown, any>;
|
50 |
|
51 | type PendingAction = ReturnType<GenericAsyncThunk["pending"]>;
|
52 | type RejectedAction = ReturnType<GenericAsyncThunk["rejected"]>;
|
53 | type FulfilledAction = ReturnType<GenericAsyncThunk["fulfilled"]>;
|
54 |
|
55 | const initialState: Record<string, string> = {};
|
56 | const resetAction = createAction("reset-tracked-loading-state");
|
57 |
|
58 | function isPendingAction(action: AnyAction): action is PendingAction {
|
59 | return action.type.endsWith("/pending");
|
60 | }
|
61 |
|
62 | const reducer = createReducer(initialState, (builder) => {
|
63 | builder
|
64 | .addCase(resetAction, () => initialState)
|
65 | // matcher can be defined outside as a type predicate function
|
66 | .addMatcher(isPendingAction, (state, action) => {
|
67 | state[action.meta.requestId] = "pending";
|
68 | })
|
69 | .addMatcher(
|
70 | // matcher can be defined inline as a type predicate function
|
71 | (action): action is RejectedAction => action.type.endsWith("/rejected"),
|
72 | (state, action) => {
|
73 | state[action.meta.requestId] = "rejected";
|
74 | }
|
75 | )
|
76 | // matcher can just return boolean and the matcher can receive a generic argument
|
77 | .addMatcher<FulfilledAction>(
|
78 | (action) => action.type.endsWith("/fulfilled"),
|
79 | (state, action) => {
|
80 | state[action.meta.requestId] = "fulfilled";
|
81 | }
|
82 | );
|
83 | });
|
84 | ```
|
85 | */
|
86 | addMatcher<A>(matcher: TypeGuard<A> | ((action: any) => boolean), reducer: CaseReducer<State, A extends AnyAction ? A : A & AnyAction>): Omit<ActionReducerMapBuilder<State>, 'addCase'>;
|
87 | /**
|
88 | * Adds a "default case" reducer that is executed if no case reducer and no matcher
|
89 | * reducer was executed for this action.
|
90 | * @param reducer - The fallback "default case" reducer function.
|
91 | *
|
92 | * @example
|
93 | ```ts
|
94 | import { createReducer } from '@reduxjs/toolkit'
|
95 | const initialState = { otherActions: 0 }
|
96 | const reducer = createReducer(initialState, builder => {
|
97 | builder
|
98 | // .addCase(...)
|
99 | // .addMatcher(...)
|
100 | .addDefaultCase((state, action) => {
|
101 | state.otherActions++
|
102 | })
|
103 | })
|
104 | ```
|
105 | */
|
106 | addDefaultCase(reducer: CaseReducer<State, AnyAction>): {};
|
107 | }
|
108 | export declare function executeReducerBuilderCallback<S>(builderCallback: (builder: ActionReducerMapBuilder<S>) => void): [
|
109 | CaseReducers<S, any>,
|
110 | ActionMatcherDescriptionCollection<S>,
|
111 | CaseReducer<S, AnyAction> | undefined
|
112 | ];
|
113 |
|
\ | No newline at end of file |