Skip to content

Commit 9abaec4

Browse files
authored
fix PreloadedState type for TS 4.3 (#949)
1 parent f98b9b2 commit 9abaec4

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

etc/redux-toolkit.api.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
import { Action } from 'redux';
88
import { ActionCreator } from 'redux';
99
import { AnyAction } from 'redux';
10+
import { CombinedState } from 'redux';
1011
import { default as createNextState } from 'immer';
1112
import { createSelector } from 'reselect';
1213
import { current } from 'immer';
13-
import { DeepPartial } from 'redux';
1414
import { Dispatch } from 'redux';
1515
import { Draft } from 'immer';
1616
import { freeze } from 'immer';
@@ -20,6 +20,7 @@ import { original } from 'immer';
2020
import { OutputParametricSelector } from 'reselect';
2121
import { OutputSelector } from 'reselect';
2222
import { ParametricSelector } from 'reselect';
23+
import { PreloadedState } from 'redux';
2324
import { Reducer } from 'redux';
2425
import { ReducersMapObject } from 'redux';
2526
import { Selector } from 'reselect';
@@ -127,7 +128,7 @@ export interface ConfigureStoreOptions<S = any, A extends Action = AnyAction, M
127128
devTools?: boolean | EnhancerOptions;
128129
enhancers?: StoreEnhancer[] | ConfigureEnhancersCallback;
129130
middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M;
130-
preloadedState?: DeepPartial<S extends any ? S : S>;
131+
preloadedState?: PreloadedState<CombinedState<NoInfer<S>>>;
131132
reducer: Reducer<S, A> | ReducersMapObject<S, A>;
132133
}
133134

src/configureStore.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import {
1010
AnyAction,
1111
StoreEnhancer,
1212
Store,
13-
DeepPartial,
14-
Dispatch
13+
Dispatch,
14+
PreloadedState,
15+
CombinedState
1516
} from 'redux'
1617
import {
1718
composeWithDevTools,
@@ -24,7 +25,7 @@ import {
2425
curryGetDefaultMiddleware,
2526
CurriedGetDefaultMiddleware
2627
} from './getDefaultMiddleware'
27-
import { DispatchForMiddlewares } from './tsHelpers'
28+
import { DispatchForMiddlewares, NoInfer } from './tsHelpers'
2829

2930
const IS_PRODUCTION = process.env.NODE_ENV === 'production'
3031

@@ -74,11 +75,16 @@ export interface ConfigureStoreOptions<
7475
* function (either directly or indirectly by passing an object as `reducer`),
7576
* this must be an object with the same shape as the reducer map keys.
7677
*/
77-
// NOTE: The needlessly complicated `S extends any ? S : S` instead of just
78-
// `S` ensures that the TypeScript compiler doesn't attempt to infer `S`
79-
// based on the value passed as `preloadedState`, which might be a partial
80-
// state rather than the full thing.
81-
preloadedState?: DeepPartial<S extends any ? S : S>
78+
/*
79+
Not 100% correct but the best approximation we can get:
80+
- if S is a `CombinedState` applying a second `CombinedState` on it does not change anything.
81+
- if it is not, there could be two cases:
82+
- `ReducersMapObject<S, A>` is being passed in. In this case, we will call `combineReducers` on it and `CombinedState<S>` is correct
83+
- `Reducer<S, A>` is being passed in. In this case, actually `CombinedState<S>` is wrong and `S` would be correct.
84+
As we cannot distinguish between those two cases without adding another generic paramter,
85+
we just make the pragmatic assumption that the latter almost never happens.
86+
*/
87+
preloadedState?: PreloadedState<CombinedState<NoInfer<S>>>
8288

8389
/**
8490
* The store enhancers to apply. See Redux's `createStore()`.
@@ -173,5 +179,5 @@ export function configureStore<
173179

174180
const composedEnhancer = finalCompose(...storeEnhancers) as any
175181

176-
return createStore(rootReducer, preloadedState as any, composedEnhancer)
182+
return createStore(rootReducer, preloadedState, composedEnhancer)
177183
}

0 commit comments

Comments
 (0)