在Redux Saga中编写泛型生成器函数时遇到的TypeScript类型报错问题
问题原因
- 报错的核心是Redux Saga的
callEffect重载类型在处理未固化的泛型函数类型Fn时,无法自动匹配Parameters<Fn>和你传入的input参数的对应关系。 - 你之前的写法中
Fn extends (input: T) => any的约束仅作用于泛型校验阶段,TS在推导call的参数类型时,不会主动关联Parameters<Fn>和T的等价关系。 - 最开始的yield隐式any报错,是因为Generator类型的第三个参数(代表yield表达式的返回值类型)没有明确声明。
解决方案
有两种常用的修复方式,都可以同时解决两类类型报错:
方案1:简化泛型定义(更推荐)
直接将函数的入参和返回值作为泛型参数,不需要额外定义Fn类型,TS可以直接完成类型推断,兼容同步、异步入参函数:
import { call, put, StrictEffect } from 'redux-saga/effects'; // 这里仅为示例,可替换为你实际的putAction类型定义 declare function putAction<D>(data: D): { type: string; payload: D }; function* test<T, R>(fn: (input: T) => Promise<R> | R, input: T): Generator<StrictEffect, void, R> { const data = yield call(fn, input); yield put(putAction(data)); }
这种写法泛型逻辑更清晰,不需要手动指定call的泛型参数,也不需要额外给data变量加类型注解。
方案2:显式指定call的泛型参数
如果你需要保留Fn的泛型定义,可以在调用call时显式传入函数的泛型类型,让TS跳过自动推断:
import { call, put, StrictEffect, SagaReturnType } from 'redux-saga/effects'; declare function putAction<D>(data: D): { type: string; payload: D }; function* test<T, Fn extends (input: T) => any>(fn: Fn, input: T): Generator<StrictEffect, void, SagaReturnType<Fn>> { // 显式指定call的泛型参数为Fn,完成参数匹配 const data = yield call<Fn>(fn, input); yield put(putAction(data)); }
内容的提问来源于stack exchange,提问作者Jeff Williams
相关产品推荐
相关产品推荐

