Resolve "Cannot invoke an expression whose type does not have a call signature <typescript - Visual Studio C # React / Redux template
When I create a new project using the C # React / Redux web application template in Visual Studio, an error is reported in the file \ ClientApp \ configureStore.ts.
"createStoreWithMiddleware (allReducers, initialState)" is underlined in red and the message says:
"TS2349 (TS) Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures."
STEPS REPROP .:
- Open VS 2017 Community Edition version 15.3.4
- Create a new C # web project using .NET framework 4.7
- Select React / Redux Web Application Template and .NET Core Version 2.0
- When the project loads, there are no npm dependencies, so I resolve the dependencies by opening the project folder in the package manager console and typing "npm install npm @latest -g"
- After that, the site will be loaded and the site will work fine. However, "createStoreWithMiddleware (allReducers, initialState)" shows an error as described above.
I don’t want to just ignore the error or suppress it, because I suspect that this may be a simple case of either defining a call signature (or cast?). My knowledge of Typescript is almost absent, so apologize if this is an extremely important issue.
[UPDATE] . It turns out that if I delete the next line of code, the error will no longer be displayed. Naturally, this means that the devTools extension will not work, so I need to figure out what this line does to make it work without causing an error.
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
The code for the "configureStore.ts" file is below - in advance for your help!
import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer, Store, StoreEnhancerStoreCreator, ReducersMapObject } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer, routerMiddleware } from 'react-router-redux';
import * as StoreModule from './store';
import { ApplicationState, reducers } from './store';
import { History } from 'history';
export default function configureStore(history: History, initialState?: 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, routerMiddleware(history)),
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
)(createStore);
// Combine all reducers and instantiate the app-wide store instance
const allReducers = buildRootReducer(reducers);
const store = createStoreWithMiddleware(allReducers, initialState) as Store<ApplicationState>;
// Enable Webpack hot module replacement for reducers
if (module.hot) {
module.hot.accept('./store', () => {
const nextRootReducer = require<typeof StoreModule>('./store');
store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
});
}
return store;
}
function buildRootReducer(allReducers: ReducersMapObject) {
return combineReducers<ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
}
, non-generic compose()
. compose<T>()
, StoreEnhancerStoreCreator<any>
. , , createStoreWithMiddleware
intellisense:
const createStoreWithMiddleware = compose<StoreEnhancerStoreCreator<any>>(
applyMiddleware(thunk, routerMiddleware(history)),
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
)(createStore);
// unchanged:
const store = createStoreWithMiddleware(allReducers, initialState) as Store<ApplicationState>;
- <any>
( # object
), . TypeScript, TypeScript. , Cat
, Dog
Human
, Mammal
. Snakes
, Animal
.