Redux: v3.6.0 breaks createStoreWithMiddleware from compose using TypeScript

Created on 23 Nov 2016  路  1Comment  路  Source: reduxjs/redux

Upgraded to v3.6.0 and now TypeScript throws the following error

Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.

import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer } from 'react-router-redux';
import * as Store from './store';

export default function configureStore(initialState?: Store.ApplicationState) {
    // Build middleware. These are functions that can process the actions before they reach the store.
    const windowIfDefined = typeof window === 'undefined' ? null : window as any;
    // If devTools is installed, connect to it
    const devToolsExtension = windowIfDefined && windowIfDefined.devToolsExtension as () => GenericStoreEnhancer;
    const createStoreWithMiddleware = compose(
        applyMiddleware(thunk),
        devToolsExtension ? devToolsExtension() : f => f
    )(createStore);

    // Combine all reducers and instantiate the app-wide store instance
    const allReducers = buildRootReducer(Store.reducers);
    // *** THE FOLLOWING LINES THROWS THE ERROR ***
    const store = createStoreWithMiddleware(allReducers, initialState) as Redux.Store<Store.ApplicationState>; 

    // Enable Webpack hot module replacement for reducers
    if (module.hot) {
        module.hot.accept('./store', () => {
            const nextRootReducer = require<typeof Store>('./store');
            store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
        });
    }

    return store;
}

function buildRootReducer(allReducers) {
    return combineReducers<Store.ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
}

Most helpful comment

Here's the working code:

import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer } from 'react-router-redux';
import * as Store from './store';

export default function configureStore(initialState?: Store.ApplicationState) {
    const windowIfDefined = typeof window === 'undefined' ? null : window as any;

    const rootReducer = buildRootReducer(Store.reducers);

    const composeEnhancers = windowIfDefined.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const store = createStore(rootReducer, {}, composeEnhancers(
        applyMiddleware(thunk)
    ));

    // Enable Webpack hot module replacement for reducers
    if (module.hot) {
        module.hot.accept('./store', () => {
            const nextRootReducer = require<typeof Store>('./store');
            store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
        });
    }

    return store;
}

function buildRootReducer(allReducers) {
    return combineReducers<Store.ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
}

>All comments

Here's the working code:

import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer } from 'react-router-redux';
import * as Store from './store';

export default function configureStore(initialState?: Store.ApplicationState) {
    const windowIfDefined = typeof window === 'undefined' ? null : window as any;

    const rootReducer = buildRootReducer(Store.reducers);

    const composeEnhancers = windowIfDefined.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const store = createStore(rootReducer, {}, composeEnhancers(
        applyMiddleware(thunk)
    ));

    // Enable Webpack hot module replacement for reducers
    if (module.hot) {
        module.hot.accept('./store', () => {
            const nextRootReducer = require<typeof Store>('./store');
            store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
        });
    }

    return store;
}

function buildRootReducer(allReducers) {
    return combineReducers<Store.ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
}
Was this page helpful?
0 / 5 - 0 ratings