Upgrading redux 4 to 5
Breaking4.2.1 → 5.0.1Breaking26Deprecated8New6Changed18Fixed4Other19
BreakingUpgrade verdict
19 breaking changes.
In plain terms
- Type definitions for reducers and stores gained an extra generic parameter, and the separate PreloadedState type is gone.
- The old UMD script-tag builds are no longer published; use redux.browser.mjs from a CDN instead.
- Removes the isMinified check.
- Drops UMD build artifacts.
Must act Top 5 of 25 that need code or config changes
redux publishes official migration guides for versions 5, 5, 5. They cover more than the release notes do.
"Migrating to RTK 2.0 and Redux 5.0" migration guide ↗**please start migrating your existing legacy Redux code to use Redux Toolkit today!** ↗Redux Toolkit 2.0 + Redux core 5.0 Migration Guide ↗Drops @babel/runtime.
Installs 0 packages in all (was 1).
What you must change
Breaking19
Removes the
PreloadedState type in favour of a PreloadedState generic on Reducer, ReducersMapObject and createStore/configureStore.ReducerReducersMapObjectcreateStoreconfigureStorecombineReducersPreloadedState$CombinedStateDrops UMD build artifacts from the published package; a redux.browser.mjs file is available for CDN loading.
redux.browser.mjsdist/redux.browser.mjsRemoves the isMinified check.
isMinifiedDrops UMD build artifacts.
Drops the UMD build artifacts.
Removes the isMinified debug check.
isMinifiedRequires that action.type must be a string; store.dispatch throws if it is not.
action.typestore.dispatch()Changes the
Middleware type so the action and next parameters are typed as unknown.MiddlewarenextactionisActionMiddleware action and next parameters are now typed as unknown.
The action.type field must now be a string.
Changes store.dispatch to require that action.type must always be a string, throwing an error otherwise.
store.dispatchaction.typeRequires action types to be strings.
Changes the names and contents of published build artifacts and the exports/module/main fields in package.json to point to them.
exportsmodulemainMakes the primary build artifact an ESM file at dist/redux.mjs, with a CJS artifact and a redux.legacy-esm.js copy for Webpack 4.
dist/redux.mjsredux.legacy-esm.jsReverts the StoreEnhancer TS type change around replacing reducers, restoring the earlier definition.
StoreEnhancerMigrates the redux core package to a full {type: "module"} ESM package with an exports field, keeping CJS for compatibility.
Stops transpiling build output and targets modern JS syntax instead.
Moves all build artifacts under ./dist/ instead of separate top-level folders.
Migrates the Redux package to be full ESM.
Deprecations to plan for
Deprecated6
Deprecates the AnyAction type in favor of an UnknownAction type used everywhere.
AnyActionUnknownActionContinues to mark createStore as deprecated, a visual-only indicator with no runtime warnings.
createStoreDocuments that createStore remains deprecated with a visual strikethrough but no runtime errors or warnings.
createStoreThe createStore deprecation tag is ported.
createStorePorts the @deprecated marker for createStore and adds legacy_createStore from Redux 4.2.0.
createStorelegacy_createStoreconfigureStore()Ports the createStore deprecation and isMinified removal from the 4.x branch.
createStoreisMinifiedAPI changes
Generated by DepDelta from published .d.ts files. Not mixed with prose notes.
- added:
call ActionCreator(...args: P): A - added:
call Dispatch<T extends A>(action: T, ...extraArgs: any[]): T - added:
call Middleware(api: MiddlewareAPI<D, S>): (next: (action: unknown) => unknown) => (action: unknown) => unknown - added:
call StoreCreator<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}, PreloadedState = S>(reducer: Reducer<S, A, PreloadedState>, preloadedState?: PreloadedState | undefined, enhancer?: StoreEnhancer<Ext>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
call StoreCreator<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
call Unsubscribe(): void - added:
const __DO_NOT_USE__ActionTypes: { INIT: string; REPLACE: string; PROBE_UNKNOWN_ACTION: () => string } - added:
declare global - added:
function applyMiddleware(): StoreEnhancer - added:
function applyMiddleware<Ext, S = any>(...middlewares: Middleware<any, S, any>[]): StoreEnhancer<{ dispatch: Ext }> - added:
function applyMiddleware<Ext1, Ext2, Ext3, Ext4, Ext5, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>, middleware4: Middleware<Ext4, S, any>, middleware5: Middleware<Ext5, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 & Ext5 }> - added:
function applyMiddleware<Ext1, Ext2, Ext3, Ext4, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>, middleware4: Middleware<Ext4, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 }> - added:
function applyMiddleware<Ext1, Ext2, Ext3, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 }> - added:
function applyMiddleware<Ext1, Ext2, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 }> - added:
function applyMiddleware<Ext1, S>(middleware1: Middleware<Ext1, S, any>): StoreEnhancer<{ dispatch: Ext1 }> - added:
function bindActionCreators<A extends ActionCreator<any>, B extends ActionCreator<any>>(actionCreator: A, dispatch: Dispatch): B - added:
function bindActionCreators<A, C extends ActionCreator<A>>(actionCreator: C, dispatch: Dispatch): C - added:
function bindActionCreators<A, M extends ActionCreatorsMapObject<A>>(actionCreators: M, dispatch: Dispatch): M - added:
function bindActionCreators<M extends ActionCreatorsMapObject, N extends ActionCreatorsMapObject>(actionCreators: M, dispatch: Dispatch): N - added:
function combineReducers<M>(reducers: M): M[keyof M] extends Reducer<any, any, any> | undefined ? Reducer<StateFromReducersMapObject<M>, ActionFromReducersMapObject<M>, Partial<PreloadedStateShapeFromReducersMapObject<M>>> : never - added:
function compose(): <R>(a: R) => R - added:
function compose<A, B, C, T extends any[], R>(f1: (c: C) => R, f2: (b: B) => C, f3: (a: A) => B, f4: Func<T, A>): Func<T, R> - added:
function compose<A, B, T extends any[], R>(f1: (b: B) => R, f2: (a: A) => B, f3: Func<T, A>): Func<T, R> - added:
function compose<A, T extends any[], R>(f1: (a: A) => R, f2: Func<T, A>): Func<T, R> - added:
function compose<F extends Function>(f: F): F - added:
function compose<R>(...funcs: Function[]): (...args: any[]) => R - added:
function compose<R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R - added:
function createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}, PreloadedState = S>(reducer: Reducer<S, A, PreloadedState>, preloadedState?: PreloadedState | undefined, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
function createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
function isAction(action: unknown): action is Action<string> - added:
function isPlainObject(obj: any): obj is object - added:
function legacy_createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}, PreloadedState = S>(reducer: Reducer<S, A, PreloadedState>, preloadedState?: PreloadedState | undefined, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
function legacy_createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, UnknownIfNonSpecific<StateExt>> & Ext - added:
index ActionCreatorsMapObject[key: string]: ActionCreator<A, P> - added:
index AnyAction[extraProps: string]: any - added:
index UnknownAction[extraProps: string]: unknown - added:
interface ActionCreator<A, P extends any[] = any[]> - added:
interface ActionCreatorsMapObject<A = any, P extends any[] = any[]> - added:
interface AnyAction extends Action - added:
interface Dispatch<A extends Action = UnknownAction> - added:
interface Middleware<_DispatchExt = {}, S = any, D extends Dispatch = Dispatch> - added:
interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> - added:
interface Store<S = any, A extends Action = UnknownAction, StateExt extends unknown = unknown> - added:
interface StoreCreator - added:
interface UnknownAction extends Action - added:
interface Unsubscribe - added:
method MiddlewareAPI.getState(): S - added:
method Store.getState(): S & StateExt - added:
method Store.replaceReducer(nextReducer: Reducer<S, A>): void - added:
method Store.subscribe(listener: ListenerCallback): Unsubscribe - added:
method Store[Symbol.observable](): Observable<S & StateExt> - added:
property MiddlewareAPI.dispatch: D - added:
property Store.dispatch: Dispatch<A> - added:
type Action<T extends string = string> = { type: T } - added:
type ActionFromReducer<R> = R extends Reducer<any, infer A, any> ? A : never - added:
type ActionFromReducersMapObject<M> = ActionFromReducer<ReducerFromReducersMapObject<M>> - added:
type Observable<T> = { subscribe: (observer: Observer<T>) => { unsubscribe: Unsubscribe }; [Symbol.observable](): Observable<T> } - added:
type Observer<T> = { next?(value: T): void } - added:
type PreloadedStateShapeFromReducersMapObject<M> = M[keyof M] extends Reducer<any, any, any> | undefined ? { [P in keyof M]: M[P] extends (inputState: infer InputState, action: UnknownAction) => any ? InputStat… - added:
type Reducer<S = any, A extends Action = UnknownAction, PreloadedState = S> = (state: S | PreloadedState | undefined, action: A) => S - added:
type ReducerFromReducersMapObject<M> = M[keyof M] extends Reducer<any, any, any> | undefined ? M[keyof M] : never - added:
type ReducersMapObject<S = any, A extends Action = UnknownAction, PreloadedState = S> = keyof PreloadedState extends keyof S ? { [K in keyof S]: Reducer<S[K], A, K extends keyof PreloadedState ? PreloadedState[K] : never> } : never - added:
type StateFromReducersMapObject<M> = M[keyof M] extends Reducer<any, any, any> | undefined ? { [P in keyof M]: M[P] extends Reducer<infer S, any, any> ? S : never } : never - added:
type StoreEnhancer<Ext extends {} = {}, StateExt extends {} = {}> = <NextExt extends {}, NextStateExt extends {}>(next: StoreEnhancerStoreCreator<NextExt, NextStateExt>) => StoreEnhancerStoreCreator<NextExt & Ext, NextStateExt… - added:
type StoreEnhancerStoreCreator<Ext extends {} = {}, StateExt extends {} = {}> = <S, A extends Action, PreloadedState>(reducer: Reducer<S, A, PreloadedState>, preloadedState?: PreloadedState | undefined) => Store<S, A, StateExt> & Ext
- removed:
call ActionCreator(...args: any[]): A - removed:
call Dispatch<T extends A>(action: T): T - removed:
call Middleware(api: MiddlewareAPI<D, S>): (next: Dispatch<AnyAction>) => (action: any) => any - removed:
call StoreCreator<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S & StateExt, A> & Ext - removed:
call StoreCreator<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext>): Store<S & StateExt, A> & Ext - removed:
call Unsubscribe(): void - removed:
declare global - removed:
function applyMiddleware(): StoreEnhancer - removed:
function applyMiddleware<Ext, S = any>(...middlewares: Middleware<any, S, any>[]): StoreEnhancer<{ dispatch: Ext }> - removed:
function applyMiddleware<Ext1, Ext2, Ext3, Ext4, Ext5, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>, middleware4: Middleware<Ext4, S, any>, middleware5: Middleware<Ext5, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 & Ext5 }> - removed:
function applyMiddleware<Ext1, Ext2, Ext3, Ext4, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>, middleware4: Middleware<Ext4, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 }> - removed:
function applyMiddleware<Ext1, Ext2, Ext3, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>, middleware3: Middleware<Ext3, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 }> - removed:
function applyMiddleware<Ext1, Ext2, S>(middleware1: Middleware<Ext1, S, any>, middleware2: Middleware<Ext2, S, any>): StoreEnhancer<{ dispatch: Ext1 & Ext2 }> - removed:
function applyMiddleware<Ext1, S>(middleware1: Middleware<Ext1, S, any>): StoreEnhancer<{ dispatch: Ext1 }> - removed:
function bindActionCreators<A extends ActionCreator<any>, B extends ActionCreator<any>>(actionCreator: A, dispatch: Dispatch): B - removed:
function bindActionCreators<A, C extends ActionCreator<A>>(actionCreator: C, dispatch: Dispatch): C - removed:
function bindActionCreators<A, M extends ActionCreatorsMapObject<A>>(actionCreators: M, dispatch: Dispatch): M - removed:
function bindActionCreators<M extends ActionCreatorsMapObject<any>, N extends ActionCreatorsMapObject<any>>(actionCreators: M, dispatch: Dispatch): N - removed:
function combineReducers<M extends ReducersMapObject<any, any>>(reducers: M): Reducer<CombinedState<StateFromReducersMapObject<M>>, ActionFromReducersMapObject<M>> - removed:
function combineReducers<S, A extends Action = AnyAction>(reducers: ReducersMapObject<S, A>): Reducer<CombinedState<S>, A> - removed:
function combineReducers<S>(reducers: ReducersMapObject<S, any>): Reducer<CombinedState<S>> - removed:
function compose(): <R>(a: R) => R - removed:
function compose<A, B, C, R>(f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func0<A>): Func0<R> - removed:
function compose<A, B, C, T1, R>(f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func1<T1, A>): Func1<T1, R> - removed:
function compose<A, B, C, T1, T2, R>(f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func2<T1, T2, A>): Func2<T1, T2, R> - removed:
function compose<A, B, C, T1, T2, T3, R>(f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func3<T1, T2, T3, A>): Func3<T1, T2, T3, R> - removed:
function compose<A, B, R>(f1: (b: B) => R, f2: (a: A) => B, f3: Func0<A>): Func0<R> - removed:
function compose<A, B, T1, R>(f1: (b: B) => R, f2: (a: A) => B, f3: Func1<T1, A>): Func1<T1, R> - removed:
function compose<A, B, T1, T2, R>(f1: (b: B) => R, f2: (a: A) => B, f3: Func2<T1, T2, A>): Func2<T1, T2, R> - removed:
function compose<A, B, T1, T2, T3, R>(f1: (b: B) => R, f2: (a: A) => B, f3: Func3<T1, T2, T3, A>): Func3<T1, T2, T3, R> - removed:
function compose<A, R>(f1: (b: A) => R, f2: Func0<A>): Func0<R> - removed:
function compose<A, T1, R>(f1: (b: A) => R, f2: Func1<T1, A>): Func1<T1, R> - removed:
function compose<A, T1, T2, R>(f1: (b: A) => R, f2: Func2<T1, T2, A>): Func2<T1, T2, R> - removed:
function compose<A, T1, T2, T3, R>(f1: (b: A) => R, f2: Func3<T1, T2, T3, A>): Func3<T1, T2, T3, R> - removed:
function compose<F extends Function>(f: F): F - removed:
function compose<R>(...funcs: Function[]): (...args: any[]) => R - removed:
function compose<R>(f1: (b: any) => R, ...funcs: Function[]): (...args: any[]) => R - removed:
function createStore<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S & StateExt, A> & Ext - removed:
function createStore<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext>): Store<S & StateExt, A> & Ext - removed:
function legacy_createStore<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S & StateExt, A> & Ext - removed:
function legacy_createStore<S, A extends Action, Ext, StateExt>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext>): Store<S & StateExt, A> & Ext - removed:
index ActionCreatorsMapObject[key: string]: ActionCreator<A> - removed:
index AnyAction[extraProps: string]: any - removed:
interface Action<T = any> - removed:
interface ActionCreator<A> - removed:
interface ActionCreatorsMapObject<A = any> - removed:
interface AnyAction extends Action - removed:
interface Dispatch<A extends Action = AnyAction> - removed:
interface Middleware<DispatchExt = {}, S = any, D extends Dispatch = Dispatch> - removed:
interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> - removed:
interface Store<S = any, A extends Action = AnyAction> - removed:
interface StoreCreator - removed:
interface Unsubscribe - removed:
method MiddlewareAPI.getState(): S - removed:
method Store.getState(): S - removed:
method Store.replaceReducer(nextReducer: Reducer<S, A>): void - removed:
method Store.subscribe(listener: () => void): Unsubscribe - removed:
method Store[Symbol.observable](): Observable<S> - removed:
property Action.type: T - removed:
property MiddlewareAPI.dispatch: D - removed:
property Store.dispatch: Dispatch<A> - removed:
type ActionFromReducer<R> = R extends Reducer<any, infer A> ? A : never - removed:
type ActionFromReducersMapObject<M> = M extends ReducersMapObject<any, any> ? ActionFromReducer<ReducerFromReducersMapObject<M>> : never - removed:
type CombinedState<S> = EmptyObject & S - removed:
type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] } - removed:
type Observable<T> = { subscribe: (observer: Observer<T>) => { unsubscribe: Unsubscribe }; [Symbol.observable](): Observable<T> } - removed:
type Observer<T> = { next?(value: T): void } - removed:
type PreloadedState<S> = Required<S> extends EmptyObject ? S extends CombinedState<infer S1> ? { [K in keyof S1]?: S1[K] extends object ? PreloadedState<S1[K]> : S1[K] } : S : { [K in… - removed:
type Reducer<S = any, A extends Action = AnyAction> = (state: S | undefined, action: A) => S - removed:
type ReducerFromReducersMapObject<M> = M extends { [P in keyof M]: infer R } ? R extends Reducer<any, any> ? R : never : never - removed:
type ReducersMapObject<S = any, A extends Action = Action> = { [K in keyof S]: Reducer<S[K], A> } - removed:
type StateFromReducersMapObject<M> = M extends ReducersMapObject<any, any> ? { [P in keyof M]: M[P] extends Reducer<infer S, any> ? S : never } : never - removed:
type StoreEnhancer<Ext = {}, StateExt = {}> = (next: StoreEnhancerStoreCreator) => StoreEnhancerStoreCreator<Ext, StateExt> - removed:
type StoreEnhancerStoreCreator<Ext = {}, StateExt = {}> = <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>) => Store<S & StateExt, A> & Ext