2017-07-17 6 views
1

TypeScriptのユニオンタイプを誤解しているか、マニュアルが正しくありません。 advanced typesセクションでは、次の例で言います:私たちは組合型を持つ値を持っている場合はUnionは、すべてのタイプに共通でないメンバーにアクセスできるようにします。

、私たちは、労働組合のすべてのタイプに共通しているメンバー にのみアクセスすることができます。

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

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

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

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

しかし、私の現在の活字体のプロジェクトで、私はそれは私がすることはできませんと言う、まさにやっているようです。タイプに切り替え関数に渡されます(それが呼ばれていますよう)

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をした後、(:私は2つの他のタイプで構成される労働組合のタイプであるタイプ(FilterAction)、FilterByReportTypeFilterByTagに作成しましたこれは驚くべき部分です)、組合のすべてのタイプに共通しないメンバーにアクセスすることができます。

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のフロー解析では、actionFilterByTagであり、もはやFilterActionではないことがわかります。活字体で

もっと

識別型の労働組合:https://basarat.gitbooks.io/typescript/content/docs/types/discriminated-unions.html

+0

私はそれが差別化された組合であるために「親切な」特性を持たなければならないと思った – Leahcim

関連する問題