Union允许我访问所有类型不常见的成员

时间:2017-07-17 15:38:16

标签: typescript

我要么误解TypeScript中的联合类型,要么文档不正确。在advanced types部分中,它使用以下示例说明:

  

如果我们有一个具有联合类型的值,我们只能访问成员   这对于工会中的所有类型都是通用的。

interface Bird {
    fly();
    layEggs();
}

interface Fish {
    swim();
    layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim();    // errors

然而,在我目前的TypeScript项目中,我似乎完全按照我所说的那样做。我创建了一个类型(FilterAction),它是由另外两种类型FilterByReportTypeFilterByTag组成的联合类型:

export type FilterAction = FilterByReportType | FilterByTag | FilterByCoffeeFlavour  

export interface FilterByType {
    type: constants.FILTER_BY_TYPE;
    report_type: string;
}
export interface FilterByTag {
    type: constants.FILTER_BY_TAG;
    tag: string;
}
 export interface FilterByCoffeeFlavour {
    type: constants.FILTER_BY_COFFEE_FLAVOUR;
    coffeeFlavour: string;
}

action(因为它被调用)被传递给一个打开该类型的函数,然后(这是令人惊讶的部分)它能够访问该成员并不是联盟中所有类型的共同点。

function filters(state: Filter = initialState, action: FilterAction) : Filter {
  switch (action.type) {
    case c.FILTER_BY_TAG:
       return Object.assign({}, state, { filterType: "tag", secondaryFilter: action.tag}) //accessing the uncommon member here w/o problem
    case c.FILTER_BY_REPORT_TYPE:
      return Object.assign({}, state, { filterType: action.report_type, secondaryFilter: ""})
   case c.FILTER_BY_COFFEE_FLAVOUR:
      return Object.assign({}, state, { filterType: action.coffeeFlavour, secondaryFilter: ""})
    default:
      return state;
  }
}

此外,例如,当我打开FILTER_BY_TAG并尝试从其他类型之一(例如coffeeFlavour)访问成员时,那么TypeScript(正确地)会抱怨{ FilterByTag上不存在{1}},这进一步强化了我的工会正如我所希望的那样工作。

为什么在这种情况下我能够访问所有类型的联合并不常见的成员,或者相反,我的用例如何不进入文档中描述的联合范围?

1 个答案:

答案 0 :(得分:1)

这是您希望发生错误但未发生错误的行:

return Object.assign({}, state, { filterType: "tag", secondaryFilter: action.tag}) //accessing the uncommon member here w/o problem

它没有发生的原因:因为它在case c.FILTER_BY_TAG:下面这告诉TypeScript 类型并且由于TypeScript的流分析,它知道action的类型为{{ 1}}而不再是FilterByTag

更多

TypeScript中的歧视联盟:https://basarat.gitbooks.io/typescript/content/docs/types/discriminated-unions.html