-
-
Notifications
You must be signed in to change notification settings - Fork 82
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
Wrong return type of combineReducers #74
Comments
Would you help me fix typescript types error with |
If redux-immutable's This may be a significant problem. Doing that, inferring app state from // src/store/index.ts
import { systemReducer } from './system/reducers'
import { chatReducer } from './chat/reducers'
const rootReducer = combineReducers({
system: systemReducer,
chat: chatReducer
})
// Here the app's entire state type is inferred from the
// return type of the reducer combineReducers returns
export type AppState = ReturnType<typeof rootReducer> Having type safety for your entire application from the root level in one type variable can be very useful. Though, when redux-immutable's However, not all is lost. Our reducers enforce type safety on smaller slices of our application state. This issue only effects type safety at a root level. For example, using I hope this comment helps. |
I've done a little digging. // Type definitions for redux-immutable v4.0.0
// Project: https://github.com/gajus/redux-immutable
// Definitions by: Pedro Pereira <https://github.com/oizie>
// Sebastian Sebald <https://github.com/sebald>
// Gavin Gregory <https://github.com/gavingregory>
// Kanitkorn Sujautra <https://github.com/lukyth>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
import { ReducersMapObject, Reducer, Action } from 'redux';
import { Collection } from 'immutable';
export declare function combineReducers<S, A extends Action, T>(reducers: ReducersMapObject<S, A>, getDefaultState?: () => Collection.Keyed<T, S>): Reducer<S, A>;
export declare function combineReducers<S, A extends Action>(reducers: ReducersMapObject<S, A>, getDefaultState?: () => Collection.Indexed<S>): Reducer<S, A>;
export declare function combineReducers<S>(reducers: ReducersMapObject<S, any>, getDefaultState?: () => Collection.Indexed<S>): Reducer<S>; I think the above type declaration file for redux-immutable provides some information. Though, my abilities in diagnosing this are inadequate for the issue to stand out to me. I would be grateful for anyone who can help out. |
Like I said, the return type of the reducer I think the reason why I cannot set generic parameter export type ReducersMapObject<S = any, A extends Action = Action> = {
[K in keyof S]: Reducer<S[K], A>
}
Might be totally wrong here. I am just going to try and write my own combineReducers that works with Immutable. |
I wrote a root reducer function by hand to get it to return the root application state as an export const rootReducer = (state: Map<string, any> = Map(), action: any) => {
return Map({
todos: todosReducer(state.get('todos'), action)
})
}
const store = createStore(rootReducer) |
I find a way . Just wrap the // src/store/index.ts
import { Record } from 'immutable'
import { combineReducers } from 'redux-immutable'
import { systemReducer } from './system/reducers'
import { chatReducer } from './chat/reducers'
const rootReducer = combineReducers({
system: systemReducer,
chat: chatReducer
})
export type AppState = Record<ReturnType<typeof rootReducer>> |
I think it works only one level deep. If you try to get some properties one level deeper it will gives you wrong types (at least Visual Studio Code doesn't provide autosuggestion). Correct me if I wrong. |
|
combineReducers.ts: import { AnyAction, ReducersMapObject } from "redux";
import Immutable from "immutable";
import { getUnexpectedInvocationParameterMessage } from "./utilities";
export default <S extends Immutable.Map<string, any>>(
reducers: ReducersMapObject<any, AnyAction>,
getDefaultState: () => S
): ((inputState: S | undefined, action: AnyAction) => S) => {
const reducerKeys = Object.keys(reducers);
// eslint-disable-next-line space-infix-ops
return (inputState: S | undefined, action: AnyAction): S => {
if (typeof inputState === "undefined") {
inputState = getDefaultState();
}
// eslint-disable-next-line no-process-env
if (process.env.NODE_ENV !== "production") {
const warningMessage = getUnexpectedInvocationParameterMessage<S>(
inputState,
reducers,
action
);
if (warningMessage) {
// eslint-disable-next-line no-console
console.error(warningMessage);
}
}
return inputState.withMutations(temporaryState => {
reducerKeys.forEach(reducerName => {
const reducer = reducers[reducerName];
const currentDomainState = temporaryState.get(reducerName);
const nextDomainState = reducer(currentDomainState, action);
if (nextDomainState === undefined) {
throw new Error(
'Reducer "' +
reducerName +
'" returned undefined when handling "' +
action.type +
'" action. To ignore an action, you must explicitly return the previous state.'
);
}
temporaryState.set(reducerName, nextDomainState);
});
});
};
}; |
Hello,
I am using
redux-immutable
withTypeScript
and found this issue.The
combineReducer
(provided byredux-immutable
) returns a plain object instead ofImmutable.Collection
.Such typing force me to do
state.sidebar
instead ofstate.get('sidebar')
inmapStateToProps
.The text was updated successfully, but these errors were encountered: