angular-redux / store

Angular 2+ bindings for Redux
MIT License
1.34k stars 205 forks source link

Passing rootreducer to the configureStore method fails compilation #539

Open cholt0425 opened 5 years ago

cholt0425 commented 5 years ago

This is a...

What toolchain are you using for transpilation/bundling?

Environment

NodeJS Version: 8.11.3 Typescript Version: 2.9.3 Angular Version: 6.1.3 @angular-redux/store version: ^9.0.0 @angular/cli version: (if applicable): 6.1.2 OS: Windows

Expected Behavior:

I have the following types and reducers defined (abbreviated for clarity)


//-- Normalized model objects suitable for the store that use string keys --//
export interface NormalizedObjectsStr<T> {
    byId: LookupNum<T>;
    allIds: number[];
}

//-- Normalized model objects suitable for the store that use string keys --//
export interface NormalizedObjectsNum<T> {
    byId: { [id: number]: T };
    allIds: number[];
}

//-- Client side store of our data models --//
export interface ClientDataStore {
    categories: NormalizedObjectsNum<Category>
    attributes: NormalizedObjectsNum<Attribute>
}

// Definition of application state
export interface IAppState {
    entities?: ClientDataStore;
    classfnAppState?: IClassfnAppState;
}

//-- Entity reducers --//
const categoriesByIdReducer: Reducer<LookupNum<Category>, FluxStandardAction<Category | number>> = (state, action) => {
    switch (action.type) {
        default: { return state; }
    }
}

const allCategoryIdsReducer: Reducer<number[], FluxStandardAction<Category | number>> = (state, action) => {
    switch (action.type) {
        default: {
            return state;
        }
    }
}

const attributesByIdReducer: Reducer<LookupNum<Attribute>, FluxStandardAction<Category | number>> = (state, action) => {
    switch (action.type) {
        default: { return state; }
    }
}

const allAttributesIdsReducer: Reducer<number[], FluxStandardAction<Attribute | number>> = (state, action) => {
    switch (action.type) {
        default: {
            return state;
        }
    }
}

const categoriesReducer = combineReducers({
    byId: categoriesByIdReducer,
    allIds: allCategoryIdsReducer
});

const attributesReducer = combineReducers({

});

const entityReducer = combineReducers({
    categories: categoriesReducer,
    attributes: attributesReducer
});

//-- Create Root Reducer --//
export default combineReducers({
    entities: entityReducer,
    classfnAppState: classfnRootReducer
});

When I configure the store with this call:

import appRootReducer from './reducers';
store.configureStore(
            appRootReducer,
            INITIAL_STATE,
            [createLogger()],
            devTools.isEnabled() ? [devTools.enhancer()] : []);

It should compile and run.

Actual Behavior:

It won't compile with an error saying the reducer type is wrong. Notice it seems to have lost the type ClientDataStore for some reason. Because I'm combining multiple reducers across the state it seems to loose the intermediate interface definition.

Stack Trace/Error Message:

ERROR in src/app/classification/classification.component.ts(14,18): error TS2339: Property 'entities' does not exist on type 'IAppStateClassfn'. src/app/store/store.module.ts(33,13): error TS2345: Argument of type 'Reducer<{ entities: { categories: any; attributes: any; }; classfnAppState: IClassfnAppState; }, ...' is not assignable to parameter of type 'Reducer<IAppState, AnyAction>'. Types of parameters 'state' and 'state' are incompatible. Type 'IAppState' is not assignable to type '{ entities: { categories: any; attributes: any; }; classfnAppState: IClassfnAppState; }'. Property 'entities' is optional in type 'IAppState' but required in type '{ entities: { categories: any; attributes: any; }; classfnAppState: IClassfnAppState; }'.

Additional Notes:

(optional)