Skip to content

Commit ed00f97

Browse files
committed
Require enhancer to be a callback
1 parent 098353c commit ed00f97

File tree

3 files changed

+45
-26
lines changed

3 files changed

+45
-26
lines changed

packages/toolkit/src/configureStore.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323
ExtractStoreExtensions,
2424
ExtractStateExtensions,
2525
} from './tsHelpers'
26-
import type { EnhancerArray, MiddlewareArray } from './utils'
26+
import type { MiddlewareArray, EnhancerArray } from './utils'
2727
import type { GetDefaultEnhancers } from './getDefaultEnhancers'
2828
import { buildGetDefaultEnhancers } from './getDefaultEnhancers'
2929

@@ -82,7 +82,7 @@ export interface ConfigureStoreOptions<
8282
* and should return a new array (such as `getDefaultEnhancers().concat(offline)`).
8383
* If you only need to add middleware, you can use the `middleware` parameter instead.
8484
*/
85-
enhancers?: ((getDefaultEnhancers: GetDefaultEnhancers<M>) => E) | E
85+
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E
8686
}
8787

8888
export type Middlewares<S> = ReadonlyArray<Middleware<{}, S>>
@@ -174,13 +174,18 @@ export function configureStore<
174174
const middlewareEnhancer = applyMiddleware(...finalMiddleware)
175175

176176
const getDefaultEnhancers = buildGetDefaultEnhancers<M>(middlewareEnhancer)
177+
178+
if (!IS_PRODUCTION && enhancers && typeof enhancers !== 'function') {
179+
throw new Error('"enhancers" field must be a callback')
180+
}
181+
177182
let storeEnhancers =
178-
(typeof enhancers === 'function'
183+
typeof enhancers === 'function'
179184
? enhancers(getDefaultEnhancers)
180-
: enhancers) ?? getDefaultEnhancers()
185+
: getDefaultEnhancers()
181186

182187
if (!IS_PRODUCTION && !Array.isArray(storeEnhancers)) {
183-
throw new Error('enhancers must be an array')
188+
throw new Error('"enhancers" callback must return an array')
184189
}
185190
if (
186191
!IS_PRODUCTION &&
@@ -196,7 +201,7 @@ export function configureStore<
196201
!storeEnhancers.includes(middlewareEnhancer)
197202
) {
198203
console.error(
199-
'middlewares were provided, but middleware enhancer was not included in final enhancers'
204+
'middlewares were provided, but middleware enhancer was not included in final enhancers - make sure to call `getDefaultEnhancers`'
200205
)
201206
}
202207

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,28 @@ describe('configureStore', async () => {
283283
undefined,
284284
expect.any(Function)
285285
)
286+
287+
expect(dummyEnhancerCalled).toBe(true)
286288
})
287289

288-
it('accepts a callback for customizing enhancers', () => {
289-
const store = configureStore({
290-
reducer,
291-
enhancers: (getDefaultEnhancers) =>
292-
getDefaultEnhancers().concat(dummyEnhancer),
290+
describe('invalid arguments', () => {
291+
test('enhancers is not a callback', () => {
292+
expect(() => configureStore({ reducer, enhancers: [] as any })).toThrow(
293+
'"enhancers" field must be a callback'
294+
)
293295
})
294296

295-
expect(dummyEnhancerCalled).toBe(true)
297+
test('callback fails to return array', () => {
298+
expect(() =>
299+
configureStore({ reducer, enhancers: (() => {}) as any })
300+
).toThrow('"enhancers" callback must return an array')
301+
})
302+
303+
test('array contains non-function', () => {
304+
expect(() =>
305+
configureStore({ reducer, enhancers: (() => ['']) as any })
306+
).toThrow('each enhancer provided to configureStore must be a function')
307+
})
296308
})
297309

298310
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
@@ -306,20 +318,20 @@ describe('configureStore', async () => {
306318
it('warns if middleware enhancer is excluded from final array when middlewares are provided', () => {
307319
const store = configureStore({
308320
reducer,
309-
enhancers: new EnhancerArray(dummyEnhancer),
321+
enhancers: () => new EnhancerArray(dummyEnhancer),
310322
})
311323

312324
expect(dummyEnhancerCalled).toBe(true)
313325

314326
expect(consoleSpy).toHaveBeenCalledWith(
315-
'middlewares were provided, but middleware enhancer was not included in final enhancers'
327+
'middlewares were provided, but middleware enhancer was not included in final enhancers - make sure to call `getDefaultEnhancers`'
316328
)
317329
})
318330
it("doesn't warn when middleware enhancer is excluded if no middlewares provided", () => {
319331
const store = configureStore({
320332
reducer,
321333
middleware: new MiddlewareArray(),
322-
enhancers: new EnhancerArray(dummyEnhancer),
334+
enhancers: () => new EnhancerArray(dummyEnhancer),
323335
})
324336

325337
expect(dummyEnhancerCalled).toBe(true)

packages/toolkit/src/tests/configureStore.typetest.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ const _anyMiddleware: any = () => () => () => {}
152152

153153
const store = configureStore({
154154
reducer: () => 0,
155-
enhancers: new EnhancerArray(enhancer),
155+
enhancers: () => new EnhancerArray(enhancer),
156156
})
157157

158158
const store2 = configureStore({
159159
reducer: () => 0,
160160
// @ts-expect-error
161-
enhancers: [enhancer],
161+
enhancers: () => [enhancer],
162162
})
163163

164164
expectType<Dispatch & ThunkDispatch<number, undefined, AnyAction>>(
@@ -169,7 +169,7 @@ const _anyMiddleware: any = () => () => () => {}
169169
configureStore({
170170
reducer: () => 0,
171171
// @ts-expect-error
172-
enhancers: new EnhancerArray('not a store enhancer'),
172+
enhancers: () => new EnhancerArray('not a store enhancer'),
173173
})
174174

175175
{
@@ -197,10 +197,11 @@ const _anyMiddleware: any = () => () => () => {}
197197

198198
const store = configureStore({
199199
reducer: () => 0,
200-
enhancers: new EnhancerArray(
201-
somePropertyStoreEnhancer,
202-
anotherPropertyStoreEnhancer
203-
),
200+
enhancers: () =>
201+
new EnhancerArray(
202+
somePropertyStoreEnhancer,
203+
anotherPropertyStoreEnhancer
204+
),
204205
})
205206

206207
expectType<Dispatch>(store.dispatch)
@@ -259,10 +260,11 @@ const _anyMiddleware: any = () => () => () => {}
259260

260261
const store = configureStore({
261262
reducer: () => ({ aProperty: 0 }),
262-
enhancers: new EnhancerArray(
263-
someStateExtendingEnhancer,
264-
anotherStateExtendingEnhancer
265-
),
263+
enhancers: () =>
264+
new EnhancerArray(
265+
someStateExtendingEnhancer,
266+
anotherStateExtendingEnhancer
267+
),
266268
})
267269

268270
const state = store.getState()

0 commit comments

Comments
 (0)