解决"Cannot invoke an expression whose type lacks a call signature"打字稿错误 - Visual Studio C# React / Re



当我使用C#React/Redux Web应用程序模板创建一个新项目时,在" clientapp configurestore.ts"文件中报告了一个错误。

" streateStorewithmiddleware(Allreducer,initialstate)"是带下划线的红色,错误状态:

"TS2349 (TS) Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures."

repro步骤:

  • Open VS 2017社区版版本15.3.4
  • 使用.NET Framework创建一个新的C#Web项目4.7
  • 选择React/Redux Web应用程序模板和.NET Core版本2.0
  • 当项目加载时,npm依赖关系丢失了,因此我通过在软件包管理器控制台中打开项目文件夹并键入" NPM install npm npm@最新-G"
  • 来解决依赖关系。
  • 此后,该站点现在将加载,并且该站点似乎正常工作。但是," streateStorewithmiddleware(Allreducer,initialstate)"显示了上述错误。

我不愿简单地忽略错误或抑制错误,因为我怀疑这可能是定义呼叫签名(或铸造?)的简单情况。我的打字稿知识几乎不存在,所以如果这是一个非常基本的问题,则很抱歉。

[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()函数返回没有定义参数的函数。此错误的最佳修复方法是明确使用返回StoreEnhancerStoreCreator<any>基本类型的通用compose<T>()函数。该类型确实会明确采用您要发送的两个参数,而调用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>(类似于C#的object类型)。它删除了Typescript的类型检查,这是使用打字稿的核心原因。因此,如果功能只能返回CatDogHuman,则将其定义为Mammal。如果以后添加Snakes,则可以将其定义为Animal

不幸的是,我不知道Spa项目模板的开发位置,因此我无法检查这是否是一个已知问题,以及是否已经开发了解决问题。

但是,您可以自己轻松地为本地项目解决此问题。这里的问题是compose函数无法返回正确键入的可呼叫,因此不允许调用createStoreWithMiddleware。您可以通过覆盖那里的类型信息来轻松解决此问题;有多种方法可以做到这一点。一个人将更改错误出现的行:

const store = (<any>createStoreWithMiddleware)(allReducers, initialState) as Store<ApplicationState>;

这将createStoreWithMiddleware投入到any类型中,该类型基本上告诉Typescript,它对它一无所知,并且只接受任何东西。由于函数调用的结果是使用as Store<ApplicationState>明确键入的,因此以后不会在任何一个上引起任何问题。

最新更新