如何在TypeScript中利用泛型正确获取Dva Dispatch的函数参数?
问题分析与解决方案
你的代码出现payload类型被合并为number & {test:'456'}的问题,核心原因有两个:
ReplaceStr类型实现错误,未能正确提取action type中的方法名;- 未对联合类型的
ActionType做分布式处理,导致TypeScript将不同方法的payload类型交叉合并。
以下是修复后的完整代码:
interface RouterAction { type: 'router-action'; } type DispatchRouterAction = (action: RouterAction) => any; interface InterfaceEffects { firstMethod(data: { payload: { test: '456' } }): any; secondMethod(data: { payload: number }): any; } // 从action type中提取斜杠后的方法名 type ExtractMethodName<ActionType extends string> = ActionType extends `${string}/${infer MethodName}` ? MethodName : never; type ActionTypeList = 'myNamespace/firstMethod' | 'myNamespace/secondMethod'; // 为每个action type生成对应的正确Action类型 type DvaAction = { [T in ActionTypeList]: { type: T; payload: Parameters<InterfaceEffects[ExtractMethodName<T>]>[0]['payload']; } }[ActionTypeList]; // 最终的dispatch类型,支持RouterAction和正确的DvaAction type DispatchCustom = (action: RouterAction | DvaAction) => any; const dispatchA = (dispatch: DispatchCustom) => { // 正确:payload类型为number dispatch({ type: 'myNamespace/secondMethod', payload: 123 }); // 正确:payload类型为{ test: '456' } dispatch({ type: 'myNamespace/firstMethod', payload: { test: '456' } }); // 正确:router-action类型 dispatch({ type: 'router-action' }); // 错误示例:payload类型不匹配,会被TypeScript提示 // dispatch({ type: 'myNamespace/secondMethod', payload: { test: '456' } }); };
关键修复点说明
替换错误的
ReplaceStr为ExtractMethodName
专门针对命名空间/方法名的格式提取方法名,逻辑更精准,避免了原递归逻辑的错误。用映射类型生成正确的联合Action类型
通过{ [T in ActionTypeList]: ... }遍历所有action type成员,为每个成员生成独立的Action类型,确保每个type对应唯一的payload类型,最终得到联合类型的DvaAction。重构
DispatchCustom类型
直接让dispatch接受RouterAction或DvaAction,TypeScript会根据传入的type自动推断payload的正确类型,不会再出现交叉合并的问题。
内容的提问来源于stack exchange,提问作者mqliutie
相关产品推荐
相关产品推荐

