Reactjs 'createAction'返回的类型不是通过'ofType'维护的`

Reactjs 'createAction'返回的类型不是通过'ofType'维护的`,reactjs,typescript,redux,redux-observable,redux-toolkit,Reactjs,Typescript,Redux,Redux Observable,Redux Toolkit,我正在制作一个应用程序,让用户从可用零食列表中选择零食。这些零食是从外部API加载的 我使用redux observable来监听操作,然后发送适当的API请求。以下是我现有的代码,并对有问题的代码行进行了注释: //行动 从'@reduxjs/toolkit'导入{createAction}; 从“./types”导入*作为类型; 常量pfx=“[零食]”; export const snackSelect=createAction`${pfx}Select`; export const sn

我正在制作一个应用程序,让用户从可用零食列表中选择零食。这些零食是从外部API加载的

我使用redux observable来监听操作,然后发送适当的API请求。以下是我现有的代码,并对有问题的代码行进行了注释:

//行动 从'@reduxjs/toolkit'导入{createAction}; 从“./types”导入*作为类型; 常量pfx=“[零食]”; export const snackSelect=createAction`${pfx}Select`; export const snackSelectSuccess=createAction`${pfx}选择成功`; export const snacksAvailableLoad=createAction`${pfx}可用负载`; export const snacksAvailableLoadSuccess=createAction`${pfx}可用加载成功`; //史诗 进口{ 组合电子学, 类型, }来自“可观察的重复次数”; 进口{ 地图 开关图, }来自“rxjs/运营商”; 从“../API”导入*作为API; 将*作为操作从“/Actions”导入; 导出默认组合 动作$=>动作$.pipe ofTypeActions.snacksAvailableLoad, switchMapAPI.snacksGet, mapActions.snacksAvailableLoadSuccess, , 动作$=>动作$.pipe ofTypeActions.snackSelect, switchMap{payload}=>API.snackSelectpayload,//错误:类型“Action”上不存在属性“payload” mapActions.snackSelectSuccess, ; 应为目标零食id的有效载荷在我的epic的开关图中不可用

我可以使用switchMapaction:ReturnType=>API.snackSelectaction.payload强制执行它,但这个ReturnType看起来像是代码气味和/或是很多样板文件

是否有正确的方法通过ofType保留键入?

如果使用filter and.match,则会推断出正确的类型:

导出默认组合 动作$=>动作$.pipe filterActions.snacksAvailableLoad.match, switchMapAPI.snacksGet, mapActions.snacksAvailableLoadSuccess, , 动作$=>动作$.pipe filterActions.snackSelect.match, switchMap{payload}=>API.snackSelectpayload, mapActions.snackSelectSuccess, , ; 如果使用过滤器和.match,则推断出正确的类型:

导出默认组合 动作$=>动作$.pipe filterActions.snacksAvailableLoad.match, switchMapAPI.snacksGet, mapActions.snacksAvailableLoadSuccess, , 动作$=>动作$.pipe filterActions.snackSelect.match, switchMap{payload}=>API.snackSelectpayload, mapActions.snackSelectSuccess, , ;
我对redux observable不太熟悉,但ofType函数中的筛选似乎是基于Action['type']属性的类型。请参阅我对类型函数声明的评论:

export declare function ofType<
  T extends Action,                     // input action type
  R extends T = T,                      // output action type
  K extends R['type'] = R['type']       // type name to filter by
>(...key: K[]): (source: Observable<T>) => Observable<R>;
或者创建某种辅助函数,因为这里似乎有一个一致的模式

第二个问题是ofType仅从类型名K推断操作类型R的能力。如果您的初始操作类型T是特定操作类型的联合,那么这可能会通过提取可分配给{type:K}的联合成员自动发生。但是如果T是一个一般的动作,那么它就不能区分它

所以你需要使用某种类型的防护装置。Redux toolkit操作附带内置类型保护功能匹配


…显然这就是您所需要的,这也解决了第一个问题。

我对redux observable不太熟悉,但ofType函数中的筛选似乎基于Action['type']属性的类型。请参阅我对类型函数声明的评论:

export declare function ofType<
  T extends Action,                     // input action type
  R extends T = T,                      // output action type
  K extends R['type'] = R['type']       // type name to filter by
>(...key: K[]): (source: Observable<T>) => Observable<R>;
或者创建某种辅助函数,因为这里似乎有一个一致的模式

第二个问题是ofType仅从类型名K推断操作类型R的能力。如果您的初始操作类型T是特定操作类型的联合,那么这可能会通过提取可分配给{type:K}的联合成员自动发生。但是如果T是一个一般的动作,那么它就不能区分它

所以你需要使用某种类型的防护装置。Redux toolkit操作附带内置类型保护功能匹配


……显然这就是你所需要的,这也解决了第一个问题。

我在给你写一个长长的蠢驴的答案,然后你就找到了一个简单的解决办法!为了公平起见,这也是我们在RTK文档中推荐的@弗瑞,我希望它写得更明确些!我完全错过了文档中的那个广告。是的,在某个时候,文档太多了。建议:使用文档的搜索功能。我刚才搜索了可观察到的,也发现了搜索的RXJS会给你相同的结果:一个文档PR来添加一个代替OfType的搜索,因此搜索很受欢迎:我正在给你写一个长长的屁股答案,然后你就找到了一个简单的解决方案!为了公平起见,这也是我们在RTK文档中推荐的@弗里一世
但愿它写得更明确些!我完全错过了文档中的那个广告。是的,在某个时候,文档太多了。建议:使用文档的搜索功能。我刚刚搜索了observable,也找到了——搜索Rxjs会给你同样的结果:添加一个docs PR,而不是ofType,所以搜索会在它上面进行,这是非常受欢迎的:
declare interface BaseActionCreator<P, T extends string, M = never, E = never> {
    type: T;
    match(action: Action<unknown>): action is PayloadAction<P, T, M, E>;
}