当我在 Visual Studio 中使用 C# React/Redux Web 应用程序模板创建新项目时,“\ClientApp\configureStore.ts”文件中报告错误。
“createStoreWithMiddleware(allReducers, initialState)”带有红色下划线且错误状态:
"TS2349 (TS) Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures."
重现步骤:
- 打开 VS 2017 Community Edition 版本 15.3.4
- 使用 .NET Framework 4.7 创建一个新的 C# Web 项目
- 选择 React/Redux Web 应用程序模板和 .NET Core 2.0 版
- 加载项目时,缺少 npm 依赖项,因此我通过在包管理器控制台中打开项目文件夹并键入“npm install npm@latest -g”来解决依赖项
- 在此之后,网站现在将加载并且网站似乎运行良好。但是,“createStoreWithMiddleware(allReducers, initialState)”会显示上述错误。
我不愿意简单地忽略错误或抑制它,因为我怀疑这可能是定义调用签名(或转换?)的简单情况。我几乎不了解 Typescript,如果这是一个非常基本的问题,我深表歉意。
[UPDATE] - 事实证明,如果我删除以下代码行,错误将不再显示。当然,这意味着 devTools 扩展将无法正常工作,因此我需要弄清楚这一行在做什么,以便让它正常工作而不会引发错误。
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
“configureStore.ts”文件的代码如下 - 在此先感谢您的帮助!
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 }));
}
最佳答案
这是因为非泛型 compose()
函数返回一个没有定义参数的函数。解决此错误的最佳方法是显式使用通用 compose<T>()
返回 StoreEnhancerStoreCreator<any>
基类型的函数.该类型确实明确采用您尝试发送的两个参数,并调用 createStoreWithMiddleware
现在将具有完整的智能感知:
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>
(类似于 C# 的 object
类型)除非那是绝对必要的。它去除了 TypeScript 的类型检查,这是使用 TypeScript 的一个核心原因。所以如果一个函数只能返回 Cat
, Dog
或 Human
, 定义为 Mammal
.如果您稍后添加 Snakes
,您可以将其定义为 Animal
.
关于typescript - 解决 "Cannot invoke an expression whose type lacks a call signature"typescript 错误 - Visual Studio C# React/Redux 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46266536/