Redux-saga+TypeScript使用takeEvery报错TakeableChannel<unknown>如何解决?
解决方法
错误根因
- 你使用Redux Toolkit的
createSlice定义fetchScreenreducer时没有显式声明payload参数,所以RTK自动将其推导为无payload的ActionCreator,和你在saga中定义的带payload的fetchScreenAction类型不匹配。 - 类型不匹配导致Typescript匹配到了错误的
takeEvery重载,将第一个参数识别为需要传入TakeableChannel类型,因此抛出缺少take属性的错误。
修复步骤
步骤1:修正slice中reducer的类型声明
给fetchScreen reducer显式添加payload类型定义,需要先从@reduxjs/toolkit导入PayloadAction类型:
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; export const screenSlice = createSlice({ name: 'screen', initialState, reducers: { // 显式声明payload类型,和你之前定义的fetchScreenPayload保持一致 fetchScreen(state, action: PayloadAction<{screenName: string}>): any { state.screen = initialState.screen; state.isLoading = true; }, }, });
步骤2:可选的兼容优化
如果改完还是有类型报错,可以直接传入action creator的type属性作为takeEvery的第一个参数,完全避开类型匹配问题:
export default function* watchDataSource() { // 换成screen.fetchScreen.type即可 yield takeEvery(screen.fetchScreen.type, fetchScreen, api); }
另外你也可以直接从slice的action creator推导saga的action类型,避免重复定义interface导致的类型不一致:
// 不用自己写fetchScreenAction接口,直接推导类型 function* fetchScreen(api: any, action: ReturnType<typeof screen.fetchScreen>) { // ... }
内容的提问来源于stack exchange,提问作者Gabriel Muñumel
相关产品推荐
相关产品推荐

