如何为Redux的dispatched函数正确标注返回类型并实现泛型
问题:为Redux Thunk调度函数正确标注返回类型
初始场景
我有如下代码,其中myAction是一个thunk:
export type ArgumentTypes<F extends Function> = F extends ( ...args: infer A ) => any ? A : never; const dispatched = <T extends Function>(action: T, args: ArgumentTypes<T>) => { const result = store.dispatch(action(args)); return result; }; const res = dispatched(myAction, null);
目前res的类型显示为any,我该如何为dispatched函数正确标注ReturnType?除该函数外,包括dispatch在内的其他部分均已正确标注类型。Redux中是否有对应类型可实现此需求?
预期res的类型应为Promise<string>。
更新后的尝试
我已将代码修改为如下形式:
const dispatched = <T extends AsyncThunk<{}, {}, {}>>( action: T, args: ArgumentTypes<T>, ) => { const result = store.dispatch(action(args)); return result; }; const res = await dispatched(myAction, null).unwrap();
现在它能正确返回AsyncThunk<>中传入的类型,但我不确定如何实现泛型适配。
解决方案
1. 基于Redux Toolkit内置类型实现泛型适配
Redux Toolkit提供了AsyncThunk的完整泛型定义,我们可以通过泛型参数捕获任意AsyncThunk的返回值、参数和配置类型,让dispatched函数自动适配所有thunk:
import { AsyncThunk } from '@reduxjs/toolkit'; // 复用你的ArgumentTypes工具类型 export type ArgumentTypes<F extends Function> = F extends ( ...args: infer A ) => any ? A : never; // 用泛型参数捕获AsyncThunk的类型信息 const dispatched = <Returned, ThunkArg, ThunkConfig>( action: AsyncThunk<Returned, ThunkArg, ThunkConfig>, args: ThunkArg ) => { return store.dispatch(action(args)); }; // 使用时自动推导类型 const res = await dispatched(myAction, null).unwrap(); // res类型为string
2. 更灵活的自动推导方案
如果不想显式依赖AsyncThunk类型,也可以直接通过store.dispatch的返回类型进行推导,兼容更多类型的action:
import { Dispatch } from '@reduxjs/toolkit'; export type ArgumentTypes<F extends Function> = F extends ( ...args: infer A ) => any ? A : never; // 让action的返回值匹配dispatch的接收类型 const dispatched = <T extends (...args: any[]) => ReturnType<Dispatch>>( action: T, ...args: ArgumentTypes<T> ) => { return store.dispatch(action(...args)); }; // 使用示例 const res = await dispatched(myAction, null).unwrap(); // 自动推导为string
核心原理
- Redux Toolkit的
AsyncThunkAction(即dispatch(thunk)的返回值)内置了.unwrap()方法,调用后会返回AsyncThunk定义的成功值类型,或抛出失败时的错误。 - 通过泛型捕获
AsyncThunk的类型参数,就能让TypeScript自动推导dispatched函数的返回类型,无需手动标注any。
内容的提问来源于stack exchange,提问作者Filip Micanek
相关产品推荐
相关产品推荐

