NGRX/Store 有效载荷类型混淆

Posted

技术标签:

【中文标题】NGRX/Store 有效载荷类型混淆【英文标题】:NGRX/Store payload type confusion 【发布时间】:2017-06-16 19:58:24 【问题描述】:

我有以下操作:

export const ActionTypes = 
  CREATE_OH:                  type('[ORDERHEAD] Create Orderhead'),
  MODIFY_SELECTED_OH:    type('[ORDERHEAD] Select Orderhead'),     
;

export class CreateOHAction implements Action 
  type = ActionTypes.CREATE_OH

  constructor(public payload: OrderHead[])  


export type Actions
  =   CreateOHAction
  |   SelectOHAction;

使用以下基本减速器设置

export interface State 
  orderids: string[];
  entities:  [orderID: string]: OrderHead ;
  selectedOhID: string | null;
;

// Set initial state to empty
const initialState: State = 
  orderids : [],
  entities: ,
  selectedOhID: null,

;
export function OHreducer(state = initialState, action: orderhead_imp.Actions):  State
      switch(action.type)

        case orderhead_imp.ActionTypes.CREATE_OH: 
            let orders = action.payload;
            let newOrders = orders.filter(orderhead => !state.entities[orderhead.orderID]);

            let newOrderIds = newOrders.map(orderhead => orderhead.orderID);
            let newOrderHeadEntities = newOrders.reduce((entities:  [orderID: string]: OrderHead , orderhead: OrderHead) => 
              return Object.assign(entities, 
                [orderhead.orderID]: orderhead
              );
            , );

            return 
              orderids: [ ...state.orderids, ...newOrderIds ],
              entities: Object.assign(, state.entities, newOrderHeadEntities),
              selectedOhID: state.selectedOhID
              ;

        default:
            return state;

    ;

但是,如果我引入另一个动作,这可以正常工作:

export class SelectOHAction implements Action 
  type = ActionTypes.MODIFY_SELECTED_OH 

  constructor(public payload: string)  

注意,仅用于此操作的有效负载是字符串,一旦保存或尝试编译,打字稿现在会指出:“过滤器不存在于字符串|OrderHead[ ]"

现在,如果我进入我的减速器,并添加一个新案例:

case orderhead_imp.ActionTypes.MODIFY_SELECTED_OH: 
 return 
  orderids:  state.orderids,
  entities: state.entities,
  selectedOhID: action.payload
;

映射 action.payload 时出现打字稿错误:

抛出 TS 错误 “string|OrderHead[] is not assignable to type string”

显然,在这两种情况下,有效负载具有不同的数据结构,我是否需要以任何其他方式更改我的代码以确保每种情况都为 action.payload 选择正确的类型?

更新

因此,如果在我的操作中我将有效负载定义为“any”而不是“string”,它似乎可以毫无问题地编译和工作,但这似乎 非常 hacky(而不是预期的行为)

export class SelectOHAction implements Action 
  type = ActionTypes.MODIFY_SELECTED_OH 

  constructor(public payload: any)  

【问题讨论】:

在您的状态下尝试 selectedOhID: string|nullselectedOhID: string 不,我首先尝试了这个,但是如果我在我的 reducer 中为 selectedOhID 设置任何类型,它仍然失败,它是来自操作中定义的有效负载值的类型检查错误,而不是来自reducer 类型定义。 您使用的是什么版本的打字稿? typescript 2.1+ 中有一个重大变化(可以说是一个错误修复),它影响了字符串文字(因此是可区分的联合)。 2.1.5,这是一个已知问题还是现在有修复? 关于这个问题的任何更新?我正在使用 ngrx 商店和效果 6.0.1 【参考方案1】:

这是 Typescript >2.1 和 ngrx 的 type util 的问题。

现在使用 typescript 2.1 及更高版本,您可以简单地将操作定义为

export const CREATE_OH: '[ORDERHEAD] Create Orderhead';
export class CreateOHAction implements Action 
   type = CREATE_OH

   constructor(public payload: OrderHead[])  

现在,在您使用 item.ActionTypes.CREATE_OH 的所有地方,将其替换为 item.CREATE_OH。 typescript 2.1 中的类型将按预期流动

【讨论】:

我的问题与原帖完全相同。我已经对我的行为进行了此更改,但问题仍然存在。

以上是关于NGRX/Store 有效载荷类型混淆的主要内容,如果未能解决你的问题,请参考以下文章

更新 ngrx/store 中的对象

InheritedWidget 混淆

如何在 @ngrx/store 的 createAction 中使用数组作为参数

Ngrx 商店收到错误,因为类型上不存在属性“ofType”

安卓混淆配置简要说明

Github GraphQL API,硬编码访问令牌有效,试图混淆它没有