-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
combineReducers is broken with TypeScript 2.6.1 and Redux 3.7.2 #2709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is likely fixed on the next branch. Wait for a 4.0 prerelease or use the index.d.ts file from there now. |
Thank you so much for answer. Should we keep it open for other people see it? I couldn't search an issue for it before. |
Hi, I faced same trouble like @lenguyenthanh . I try to put new definition file to "./typings/redux.d.ts", but it seems to be ignored while compiling. Is there no way without overwrite |
These are on the |
@timdorr Thanks a lot! |
I tried
|
You should be putting that |
@timdorr I am actually using
Error:
I think, after introduction to |
@tipng
I hope it helps. |
Except for functions because of reduxjs/redux#2709
Not very satisfying, but I've found that asserting the const combinedReducers = combineReducers({ reducer1, reducer2 } as any); Using the version 4 beta typings does not work for me. |
Check #2773. It needs a review. |
Try to add "any" as an alternative data type in you reducer: export function reducer(state = defaultState.count, action: ActionTypes | any) { ... } |
Using Typescript 3.2.4 and Redux 4.0.1, the issue remains. Used @seepel solution for now. |
Breaks for me as soon as I add a second parameter to the import { createActionCreators, createReducerFunction, ImmerReducer } from 'immer-reducer';
import { applyMiddleware, combineReducers, createStore, Reducer, Store } from 'redux';
import thunk from 'redux-thunk';
interface IUser {
id: number;
name: string;
}
type UsersById = { [id: number]: IUser };
interface IGlobalState {
usersById: UsersById;
}
type UserActions = {
type: 'create',
payload: {
id: number;
name: string;
},
};
const userReducer: Reducer<UsersById, UserActions> = (state = {}, action) => {
switch(action.type) {
case 'create':
const { id, name } = action.payload;
return Object.assign(state, {
[id]: {
id,
name,
},
});
}
};
type Actions = UserActions;
function createGlobalStore(): Store<IGlobalState, Actions> {
return createStore(
combineReducers({ usersById: userReducer, }),
applyMiddleware(thunk), // works without this line
);
} Full error: https://i.imgur.com/hH4TpyZ.png |
The problem lies here https://github.com/reduxjs/redux/blob/master/index.d.ts#L62, if undefined is removed then it will be ok |
@codeflowee The reducer will receive an undefined state on init, so that is a valid type. |
Ran into this same issue... Perhaps |
My issue ended up being that I had forgotten to pass in an initial state (i.e., export interface NavigationState {
drawerIsOpen: boolean;
}
export const defaultState: NavigationState = {
drawerIsOpen: false
};
export default function reducer(state: NavigationState = defaultState, action: any): NavigationState {
switch (action.type) {
case NavigationReduxAction.SET_DRAWER_IS_OPEN:
return {
...state,
drawerIsOpen: action.drawerIsOpen
};
default:
return state;
}
} |
I still have the issue using Typescript 3.2.6 and Redux 4.0.4. So forced to cast to |
Same problem : Typescript : 3.6.3 and Redux 4.0.4 Force to cast as any, an so I don't have any autocomplete on my mapStateToProps' state :( If you want an alternative to have the autocomplete in your mapStateToProps
The IStore is just an Interface made of all my Reducers's InitialState
|
Same here: Typescript 3.6.4, Redux 4.0.4 |
Can this be reopened? It's still a problem. Redux 4.0.4, TypeScript 3.7.2 |
For me, I was facing issues that required casting to // store/index.ts ------------------------------
import { createStore, applyMiddleware, combineReducers } from "redux"
import { composeWithDevTools } from "redux-devtools-extension"
import logger from "redux-logger"
import { appReducer as app } from "@services/app/reducer"
import { searchReducer as search } from "@services/search/reducer"
// create the root reducer
export const rootReducer = combineReducers({ app, search })
// create the store
export const store = createStore(
rootReducer,
// initialize redux devtools and the redux logger
composeWithDevTools(applyMiddleware(logger)),
)
// types/redux.d.ts ------------------------------
import { rootReducer } from "@store"
import { setEnvironment, setMode, setTheme } from "@services/app/action"
import { setSearchBy } from "@services/search/action"
/**
* `declare global` is used inside a file that has `import`
* or `export` to declare things in the global scope.
* This is necessary in files that contain `import` or
* `export` since such files are considered modules,
* and anything declared in a module is in the module scope.
*
* Using `declare global` in a file that is not a module
* (that is contains no `import`/`export`) is an error since
* everything in such a file is in the global scope anyway.
*
*/
declare global {
/**
* This is the single source of truth for all components
* that access the redux store. It infers the apps store
* using the return type of the root reducer.
*/
// type Store = ReduxState
type Store = ReturnType<typeof rootReducer>
// define the app state for the app reducer
type AppState = { theme: Theme; mode: Mode; environment: Environment }
// define the search state for the search reducer
type SearchState = { searchBy: SearchType }
// bundle app actions for the app reducer action parameter
type AppActionTypes =
| ReturnType<typeof setTheme>
| ReturnType<typeof setMode>
| ReturnType<typeof setEnvironment>
// bundle search actions for the search reducer action parameter
type SearchActionTypes = ReturnType<typeof setSearchBy>
// combine all possible action types
type AppActions = AppActionTypes | SearchActionTypes
}
// app/reducer.ts ------------------------------
import constants from "../constants"
const initialState: AppState = {
theme: "light",
mode: "search",
environment: "lower",
}
export const appReducer = (
state = initialState,
action: AppActionTypes,
): AppState => {
switch (action.type) {
case constants.THEME:
return { ...state, theme: action.payload }
case constants.MODE:
return { ...state, mode: action.payload }
case constants.ENVIRONMENT:
return { ...state, environment: action.payload }
default:
return state
}
}
// app/action.ts ------------------------------
import constants from "@constants"
/**
* Set the theme of the app.
* @param {Theme} theme
*/
export const setTheme = (theme: Theme) =>
({
type: constants.THEME,
payload: theme,
} as const)
/**
* Set the mode of the app.
* @param {Mode} mode
*/
export const setMode = (mode: Mode) =>
({
type: constants.MODE,
payload: mode,
} as const)
/**
* Set the environment of the app.
* @param {Environment} environment
*/
export const setEnvironment = (environment: Environment) =>
({
type: constants.ENVIRONMENT,
payload: environment,
} as const) |
Related to reduxjs#2709
it will break the typing, if you need to types store base on the rootReducer as I do here
instead, |
Creating a function inside const allReducers = {
auth: authReducer,
projects: projectsReducer,
navigation: navigationReducer
};
export const appReducer = combineReducers<typeof allReducers>(allReducers);
export type AppState = ReturnType<typeof appReducer>
export const store = configureStore({
reducer: (state, action) => {
if (action.type === 'auth/logout') {
return appReducer(undefined, action);
}
return appReducer(state, action);
},
devTools: process.env.NODE_ENV !== 'production',
});
export type AppDispatch = typeof store.dispatch;
export type RootState = AppState;
export type AppThunk<ReturnType = void> = ThunkAction<
ReturnType,
RootState,
unknown,
Action<string>
>; |
I modified Little & works good! export function combineReducers(reducers: any) { return (state:any, action:any) => {
} |
combineReducers is broken with TypeScript 2.6.1 and Redux 3.7.2
What is the current behavior?
Here is my code
and here is error:
What is the expected behavior?
It should compile and work.
Which versions of Redux, and which browser and OS are affected by this issue? Did this work in previous versions of Redux?
Redux 3.7.2 and Typescript 2.6.1
Hot fix
It works well if I change Reducer definition in
index.d.ts
file:And my reducer:
How do you think about this issue and hot fix?
The text was updated successfully, but these errors were encountered: