React JS转TS时Redux中间件报TS2345错误,求解释编译器提示
我太懂这种把JS React/Redux项目转TypeScript时被类型错误卡得头大的感觉了——5小时耗在一个错误上真的超折磨人!先帮你把这个TS2345错误拆解得明明白白,再给你直接能用的修复方案。
先拆解错误信息的真实含义
首先看编译器抛出的错误:
Error TS2345 (TS) Argument of type '{ loggerMiddleware: Middleware<{}, any, Dispatch
>; }' is not assignable to parameter of type 'Middleware<any, any, any>'. Type '{ loggerMiddleware: Middleware<{}, any, Dispatch >; }' provides no match for the signature '(api: MiddlewareAPI<any, any>): (next: Dispatch ) => (action: any) => any'.
翻译成大白话就是:
你传给applyMiddleware的东西不是一个符合要求的Redux中间件函数,而是一个包含中间件的对象({ loggerMiddleware: ... })。Redux的中间件要求是一个特定的高阶函数签名:(api: MiddlewareAPI) => (next: Dispatch) => (action) => any,但你传的对象根本不满足这个函数结构,所以TS直接报错了。
为什么会出现这个错误?
看你贴的代码,你写了const middleware = [ loggerMiddleware ];然后用applyMiddleware(...middleware),理论上展开数组应该传入单个中间件函数,但错误信息显示你传的是对象,大概率是你在代码里不小心把middleware的定义写成了对象而不是数组——比如误写了大括号:
// 错误写法:用了大括号,变成了对象 const middleware = { loggerMiddleware }; // 正确写法:方括号,是数组 const middleware = [ loggerMiddleware ];
如果是对象的话,...middleware会展开成对象的键值对,传给applyMiddleware的就不是函数了,自然触发类型错误。
修复步骤
1. 确保middleware是数组类型(并明确标注类型)
把middleware定义成数组,并且明确标注为Middleware[],避免TS的类型推断出错:
import { Middleware } from 'redux'; // 正确定义中间件数组 const middleware: Middleware[] = [ loggerMiddleware ];
2. 完善loggerMiddleware的类型定义
给中间件的action参数加上类型,让TS的类型检查更严谨:
import { Middleware, MiddlewareAPI, Dispatch, AnyAction } from 'redux'; const loggerMiddleware: Middleware = (api: MiddlewareAPI) => (next: Dispatch<AnyAction>) => (action: AnyAction) => { const returnValue = next(action); console.log('state after dispatch', api.getState()); return returnValue; };
如果你的项目有自定义的ApplicationState类型,还可以替换掉默认的any,让类型更精准:
import { ApplicationState } from './path-to-your-state-types'; const loggerMiddleware: Middleware<{}, ApplicationState> = (api: MiddlewareAPI<Dispatch, ApplicationState>) => (next: Dispatch<AnyAction>) => (action: AnyAction) => { const returnValue = next(action); console.log('state after dispatch', api.getState()); return returnValue; };
3. 确认applyMiddleware调用正确
确保你是展开数组传入中间件:
compose(applyMiddleware(...middleware), ...enhancers)
最后总结
这个错误的核心就是类型不匹配——你把一个对象当成了中间件函数传给了applyMiddleware。只要把middleware改成数组,再完善一下中间件的类型定义,就能解决这个卡了你5小时的问题啦!
内容的提问来源于stack exchange,提问作者tzairos

