2017-07-17 43 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