簡體   English   中英

打字稿區分聯合類型無法識別

[英]Typescript discriminated union type not recognized

我正在嘗試基於在https://github.com/ngrx/example-app/找到的示例應用程序來構建Angular 2 / ngrx應用程序。 我將動作類型導出為有區別的聯盟

export const ActionTypes = {
  QUERY: type('[Games] Query'),
  QUERY_COMPLETE: type('[Games] Query Complete'),
  INVALIDATE: type('[Games] Invalidate'),
  SELECT: type('[Games] Select'),
  LOAD_NEXT_PAGE: type('[Games] Load Next Page'),
  LOAD_NEXT_PAGE_COMPLETE: type('[Games] Load Next Page Complete'),

};

export class QueryAction implements Action {
    type = ActionTypes.QUERY;

    constructor(public payload: string) {}
}

export class QueryCompleteAction implements Action {
    type = ActionTypes.QUERY_COMPLETE;

    constructor(public payload: Game[]) {}

}

export class LoadNextPageCompleteAction implements Action {
    type = ActionTypes.LOAD_NEXT_PAGE_COMPLETE;

    constructor(public payload: Game[]) {}
}

export class LoadNextPageAction implements Action {
    type = ActionTypes.LOAD_NEXT_PAGE;

    constructor() {}
}

export class InvalidateAction implements Action {
    type = ActionTypes.INVALIDATE;

    constructor(){}
}

export class SelectAction implements Action {
    type = ActionTypes.SELECT;

    constructor(public payload: number) {}
}

export type Actions = QueryAction | QueryCompleteAction | InvalidateAction | SelectAction | LoadNextPageAction | LoadNextPageCompleteAction;

並將它們傳遞給reducer函數,根據type屬性進行區分,如下所示:

export function reducer(state = initialState, action: game.Actions): State {
  switch (action.type) {
    case game.ActionTypes.LOAD_NEXT_PAGE:
    case game.ActionTypes.QUERY: {
      return Object.assign({}, state, {loading: true});
    }
    case game.ActionTypes.QUERY_COMPLETE: {
      return {
        games: action.payload,
        offset: action.payload.length,
        loading: false,
        selectedGameId: null
      }
    }
    case game.ActionTypes.LOAD_NEXT_PAGE_COMPLETE: {
      return {
        games: [...state.games, ...action.payload],
        offset: state.offset + action.payload.length,
        loading: false,
        selectedGameId: state.selectedGameId
      }
    }
    case game.ActionTypes.SELECT: {
      return Object.assign({}, state, {selectedGameId: action.payload});
    }
    default: {
      return state;
    }
  }
}

這無法與錯誤一起編譯(以及其他錯誤)

Type 'string | number | Game[]' is not assignable to type 'Game[]'.
Type 'string' is not assignable to type 'Game[]'.
Property 'length' does not exist on type 'string | number | Game[]'.
Property 'length' does not exist on type 'number'

我是在做錯事還是不了解受歧視的工會的工作方式? 我的理解是,switch語句應縮小action.payload的可能類型,以確保它是正確的類型。 它似乎是在與工會中所有成員的類型進行比較,而不只是與匹配類型的成員進行比較。

該項目正在使用Typescript v2.1.6

請參閱此github問題提出請求

從TypeScript 2.1+中的重大更改開始,除非將字符串文字類型分配給不可變的const變量或只讀屬性,否則它們始終會擴展為字符串。 這意味着像switch(action.type)語句那樣利用已區分的並集停止使用當前的示例應用程序模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM