2017-07-17 64 views
1

我误解了TypeScript中的联合类型,或者文档不正确。在advanced types部分,它说用下面的例子:联盟让我访问所有类型不通用的成员

如果我们有一个具有联合类型的值,我们只能访问成员 是常见的在工会的所有类型。

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

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

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

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

然而,在我目前的打字稿的项目,我似乎做什么,它说我不能。我创建了一个类型(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)访问成员,则打字稿(正确)抱怨coffeeFlavour不存在在FilterByTag上,这进一步加强了我的工会如我所愿。

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

+2

这是* *在文档中描述工会的范围 - 通过'switch'ing的东西,区分各个类型,创建[* *歧视工会**](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions)。在每个case中,你知道(更重要的是,* TypeScript编译器知道*),它是更具体的类型。 – jonrsharpe

+0

我正要回答这个问题,但我不知道_“智能铸造”_的打字稿术语。 +1 @jonrsharpe –

+0

@jonsharpe好的,谢谢。尽管如此,除非扩展文档,否则您所说的和文档中所说的内容完全不同。 '如果我们有一个具有联合类型的值,那么我们只能访问联合中所有类型共有的成员。'# – Leahcim

回答

1

这是你想要发生的错误,但没有发生线路:

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

为什么它不发生的原因是:由于是case c.FILTER_BY_TAG:下这告诉打字稿中和感谢TypeScript的流程分析知道action的类型为FilterByTag,不再是FilterAction

更多

识别联合在打字稿:https://basarat.gitbooks.io/typescript/content/docs/types/discriminated-unions.html

+0

我认为它必须有一个“善良”的财产是一个歧视的工会 – Leahcim