Skip to content

Commit 54f5803

Browse files
committed
fix(configureStore): remove Action generic argument
1 parent e4725ce commit 54f5803

4 files changed

Lines changed: 29 additions & 24 deletions

File tree

docs/api/configureStore.mdx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ Redux Toolkit's `configureStore` simplifies that setup process, by doing all tha
4040

4141
interface ConfigureStoreOptions<
4242
S = any,
43-
A extends Action = UnknownAction,
4443
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
4544
E extends Tuple<Enhancers> = Tuple<Enhancers>,
4645
P = S
@@ -49,13 +48,16 @@ interface ConfigureStoreOptions<
4948
* A single reducer function that will be used as the root reducer, or an
5049
* object of slice reducers that will be passed to `combineReducers()`.
5150
*/
52-
reducer: Reducer<S, A, P> | ReducersMapObject<S, A, P>
51+
reducer: Reducer<S, any, P> | ReducersMapObject<S, any, P>
5352

5453
/**
55-
* An array of Redux middleware to install. If not supplied, defaults to
56-
* the set of middleware returned by `getDefaultMiddleware()`.
54+
* A callback which receives `getDefaultMiddleware` and should return a Tuple
55+
* of middleware to install. If not supplied, defaults to the set of
56+
* middleware returned by `getDefaultMiddleware()`.
57+
*
58+
* @example `middleware: (gDM) => gDM().concat(logger, apiMiddleware, yourCustomMiddleware)`
5759
*/
58-
middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M
60+
middleware?: (getDefaultMiddleware: GetDefaultMiddleware<S>) => M
5961

6062
/**
6163
* Whether to enable Redux DevTools integration. Defaults to `true`.
@@ -87,16 +89,15 @@ interface ConfigureStoreOptions<
8789
* and should return a new array (such as `getDefaultEnhancers().concat(offline)`).
8890
* If you only need to add middleware, you can use the `middleware` parameter instead.
8991
*/
90-
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E | E
92+
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E
9193
}
9294

9395
function configureStore<
9496
S = any,
95-
A extends Action = UnknownAction,
9697
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
9798
E extends Tuple<Enhancers> = Tuple<Enhancers>,
9899
P = S
99-
>(options: ConfigureStoreOptions<S, A, M, E, P>): EnhancedStore<S, A, M, E>
100+
>(options: ConfigureStoreOptions<S, M, E, P>): EnhancedStore<S, E>
100101
```
101102

102103
### `reducer`

packages/toolkit/src/configureStore.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type {
22
Reducer,
33
ReducersMapObject,
44
Middleware,
5-
Action,
65
StoreEnhancer,
76
Store,
87
UnknownAction,
@@ -39,16 +38,18 @@ import { buildGetDefaultEnhancers } from './getDefaultEnhancers'
3938
*/
4039
export interface ConfigureStoreOptions<
4140
S = any,
42-
A extends Action = UnknownAction,
4341
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>,
4442
E extends Tuple<Enhancers> = Tuple<Enhancers>,
4543
P = S,
4644
> {
4745
/**
4846
* A single reducer function that will be used as the root reducer, or an
4947
* object of slice reducers that will be passed to `combineReducers()`.
48+
*
49+
* The reducer may be typed to handle any action type - the resulting store
50+
* is always typed to dispatch `UnknownAction`, as recommended.
5051
*/
51-
reducer: Reducer<S, A, P> | ReducersMapObject<S, A, P>
52+
reducer: Reducer<S, any, P> | ReducersMapObject<S, any, P>
5253

5354
/**
5455
* An array of Redux middleware to install, or a callback receiving `getDefaultMiddleware` and returning a Tuple of middleware.
@@ -105,10 +106,9 @@ type Enhancers = ReadonlyArray<StoreEnhancer>
105106
*/
106107
export type EnhancedStore<
107108
S = any,
108-
A extends Action = UnknownAction,
109109
E extends Enhancers = Enhancers,
110110
> = ExtractStoreExtensions<E> &
111-
Store<S, A, UnknownIfNonSpecific<ExtractStateExtensions<E>>>
111+
Store<S, UnknownAction, UnknownIfNonSpecific<ExtractStateExtensions<E>>>
112112

113113
/**
114114
* A friendly abstraction over the standard Redux `createStore()` function.
@@ -120,13 +120,12 @@ export type EnhancedStore<
120120
*/
121121
export function configureStore<
122122
S = any,
123-
A extends Action = UnknownAction,
124123
M extends Tuple<Middlewares<S>> = Tuple<[ThunkMiddlewareFor<S>]>,
125124
E extends Tuple<Enhancers> = Tuple<
126125
[StoreEnhancer<{ dispatch: ExtractDispatchExtensions<M> }>, StoreEnhancer]
127126
>,
128127
P = S,
129-
>(options: ConfigureStoreOptions<S, A, M, E, P>): EnhancedStore<S, A, E> {
128+
>(options: ConfigureStoreOptions<S, M, E, P>): EnhancedStore<S, E> {
130129
const getDefaultMiddleware = buildGetDefaultMiddleware<S>()
131130

132131
const {
@@ -138,12 +137,16 @@ export function configureStore<
138137
enhancers = undefined,
139138
} = options || {}
140139

141-
let rootReducer: Reducer<S, A, P>
140+
let rootReducer: Reducer<S, UnknownAction, P>
142141

143142
if (typeof reducer === 'function') {
144143
rootReducer = reducer
145144
} else if (isPlainObject(reducer)) {
146-
rootReducer = combineReducers(reducer) as unknown as Reducer<S, A, P>
145+
rootReducer = combineReducers(reducer) as unknown as Reducer<
146+
S,
147+
UnknownAction,
148+
P
149+
>
147150
} else {
148151
throw new Error(
149152
'`reducer` is a required argument, and must be a function or an object of functions that can be passed to combineReducers',

packages/toolkit/src/tests/configureStore.test-d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,18 @@ describe('type tests', () => {
5656
expectTypeOf(store).not.toExtend<Store<string, UnknownAction>>()
5757
})
5858

59-
test('configureStore() infers the store action type.', () => {
59+
test('configureStore() always types the store action as `UnknownAction`.', () => {
60+
// Even if the reducer is typed to handle a specific action, the resulting
61+
// store is always typed to dispatch `UnknownAction` - `configureStore` no
62+
// longer accepts/infers a store-wide action type.
63+
// See https://github.com/reduxjs/redux-toolkit/issues/5317
6064
const reducer: Reducer<number, PayloadAction<number>> = () => 0
6165

6266
const store = configureStore({ reducer })
6367

64-
expectTypeOf(store).toExtend<Store<number, PayloadAction<number>>>()
68+
expectTypeOf(store).toExtend<Store<number, UnknownAction>>()
6569

66-
expectTypeOf(store).not.toExtend<Store<number, PayloadAction<string>>>()
70+
expectTypeOf(store).not.toExtend<Store<number, PayloadAction<number>>>()
6771
})
6872

6973
test('configureStore() accepts Tuple for middleware, but not plain array.', () => {

packages/toolkit/src/tests/utils/helpers.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,7 @@ export function setupApiStore<
181181
} & {
182182
[K in keyof R]: ReturnType<R[K]>
183183
},
184-
UnknownAction,
185-
ReturnType<typeof getStore> extends EnhancedStore<any, any, infer M>
186-
? M
187-
: never
184+
ReturnType<typeof getStore> extends EnhancedStore<any, infer M> ? M : never
188185
>
189186

190187
const initialStore = getStore() as StoreType

0 commit comments

Comments
 (0)