typescript - 解决 "Cannot invoke an expression whose type lacks a call signature"typescript 错误 - Visual Studio C# React/Redux 模板

标签 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."

重现步骤:

  • 打开 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 , DogHuman , 定义为 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/

相关文章:

arrays - 无法获取数组 Angular 中的第一项

arrays - 如果选中相同的复选框,如何循环两个数组并进行比较 Angular 2

typescript - WebStorm 和 TypeScript : how to navigate to *. ts 而不是 *.d.ts

c# - 在 .net core 中使用 linq2db 时获取 "Could not load file or assembly ' System.EnterpriseServices""

c# - 带有 .NET Core 的 NLog/SQLite

TypeScript:实现具有调用签名和索引签名的接口(interface)

routerlink 中间的 Angular 6 查询参数

c# - 如何使用 AuthorizationHandlerContext 在 ASP.NET Core 2 自定义基于策略的授权中访问当前的 HttpContext

asp.net-core - 表中的 EditForm 不呈现

c# - 模拟存储库返回 null