解析"无法调用类型缺少调用签名的表达式"typescript错误 - Visual Studio C#React/Redux模板

Tom*_*Ell 6 typescript asp.net-core

当我在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."
Run Code Online (Sandbox Code Playgroud)

重播步骤:

  • 打开VS 2017 Community Edition 15.3.4版
  • 使用.NET framework 4.7创建一个新的C#Web项目
  • 选择React/Redux Web应用程序模板和.NET Core版本2.0
  • 当项目加载时,缺少npm依赖项,因此我通过在Package Manager控制台中打开项目文件夹并键入"npm install npm @ latest -g"来解决依赖项问题.
  • 在此之后,该网站现在将加载,该网站似乎运行正常.但是,"createStoreWithMiddleware(allReducers,initialState)"显示如上所述的错误.

我不愿意简单地忽略错误或抑制错误,因为我怀疑这可能是定义调用签名(或者转换?)的简单情况.我的打字稿知识几乎不存在,如果这是一个非常基本的问题,请道歉.

[更新] - 事实证明,如果我删除以下代码行,则不再显示错误.当然这意味着devTools扩展将无法工作,所以我需要弄清楚这条线路正在做什么,以使其工作而不会抛出错误.

devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
Run Code Online (Sandbox Code Playgroud)

"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 }));
}
Run Code Online (Sandbox Code Playgroud)

ars*_*in3 13

这是因为非泛型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>;
Run Code Online (Sandbox Code Playgroud)

尽量避免使用某些东西<any>(类似于C#的object类型),除非绝对必要.它删除了TypeScript的类型检查,这是使用TypeScript的核心原因.因此,如果函数只能返回Cat,Dog或者Human将其定义为Mammal.如果稍后添加Snakes,则可以将其定义为Animal.