Typescript v2.2.2联合类型产生错误(TS2339)

时间:2017-04-14 15:47:08

标签: angular typescript ngrx

在我的角度2中,我使用ngrx并有一些动作和减速器。行动举例:

import { Action } from '@ngrx/store';

export const actionTypes = {
  ACTION_1: type('Actions 1'),
  ACTION_2: type('Actions 2'),
};

export class ActionOne implements Action {
  public type = actionTypes.ACTION_1;

  constructor(public payload: any) { }
}

export class ActionTwo implements Action {
  public type = actionTypes.ACTION_2;
}

export type Actions
  = ActionOne
  | ActionTwo;

因此,某些操作有效负载,其他操作有效 - 否,Actions是工会类型,可以是ActionOneActionTwo。但在我减速器中我有一个错误:Property 'payload' does not exist on type 'Actions' Property 'payload' does not exist on type 'ActionTwo'.

Reducer就像这样:

export function reducer(state = initialState, action: Actions): IState {
  switch (action.type) {

    case actions.actionTypes.ACTION_1: {
      return Object.assign({}, state, {
        data: action.payload,
      });
    }

    case ...
  }
}

我将打字稿版本从2.0.3更新为2.2.2后出现此错误。 那么,有没有办法在不将有效负载放到每个动作的情况下修复错误?对于这种情况,可能是tsconfog.json有一些选项吗?

2 个答案:

答案 0 :(得分:1)

您可以在命名空间中声明常量,而不是字典。这允许ACTION_1和ACTION_2采用文字类型,这对于被禁止的联盟起作用至关重要。

export namespace actionTypes {
    export const ACTION_1 = 'Action 1';  // <-- type of ACTION_1 is 'Action 1' in TS 2.1+
    export const ACTION_2 = 'Action 2';
};

每个type的{​​{1}}必须是常量,否则class的类型将是type而不是文字类型。

string

自TypeScript 2.1 / Angular 4以来,ngrx开发人员已弃用export class ActionOne implements Action { public readonly type = actionTypes.ACTION_1; // <-- note the `readonly` constructor(public payload: any) { } } export class ActionTwo implements Action { public readonly type = actionTypes.ACTION_2; } 模式。有关信息,请参阅https://github.com/ngrx/example-app/pull/88#issuecomment-272623083

答案 1 :(得分:-2)

你知道在这个开关案例中它是哪个动作,你可以转换到适当的一个:

case actions.actionTypes.ACTION_1: {
    return Object.assign({}, state, {
        data: (action as ActionOne).payload,
    });
}

编译器显然是正确的,因为联合产生的类型只有共享属性,而payload不是其中之一。