2017-03-26 4 views
0

Ich habe eine Art Szenario, in dem ich sagen will:Union und Intersection Arten Reihenfolge der Operationen?

export interface ItemSchema { 
    [attrName: string]: 
    { type: 'number', default?: number, readOnly?: boolean} | 
    { type: 'string', default?: string, readOnly?: boolean} | 
    { type: 'boolean', default?: boolean, readOnly?: boolean} | 
    { type: 'date', default?: Date, readOnly?: boolean} | 
    { type: 'object', default?: object, readOnly?: boolean} 
} 

(weil ich die Definition ein Schema, das zur Laufzeit verfügbar ist für die Daten um im JSON-Format übergeben zu werden, FWIW, und das ist die Schnittstelle für das Schema).

Dies ist praktisch, weil in meinem tatsächlichen Typ Definitionen { type: 'number', default: 2 } haben kann, aber nicht { type: 'number', default: 'potato' }.

Ich möchte das readOnly-Bit (und andere Dinge, die hier zur Vereinfachung weggelassen wurden) in ein separates Segment ziehen. Ich tatsächlich kann den obigen Stapel mit { readOnly?: boolean } & voranstellen und es scheint zu funktionieren, aber das hängt von einer bestimmten Reihenfolge der Operationen dieser | und & Betreiber, die nicht gut dokumentiert ist (zumindest nicht an einem Ort, den ich finden kann).

(in Klammern, ich kann auch Klammern verwenden, wie es scheint, {} & ({} | {} | {}), aber das macht meinen Linter ausrasten, so dass ich nicht sicher bin, ob Klammern hier offiziell unterstützt werden oder wenn es nur ein Unfall ist).

Gibt es also einen Ort, an dem die Reihenfolge der Operationen für diese Schnittstellenzusammensetzungsoperatoren definiert ist? Ich möchte keinen Code schreiben, der nur aufgrund einer undokumentierten Eigenart im Compiler läuft und 2.3 oder was auch immer einbricht.

Antwort

1

Sie können Schnittstellen verwenden.

Eine Schnittstelle für das Basisschema:

interface Schema { readOnly?: boolean }; 

Und dann anderen die, die sie verlängern:

interface NumberSchema extends Schema { type: 'number', default?: number }; 
interface BooleanSchema extends Schema { type: 'boolean', default?: boolean }; 
interface StringSchema extends Schema { type: 'string', default?: string }; 
interface DateSchema extends Schema { type: 'date', default?: Date }; 
interface ObjectSchema extends Schema { type: 'object', default?: object }; 

Dann ist die Karte:

interface ItemSchema { 
    [attrName: string]: NumberSchema | BooleanSchema | StringSchema | DateSchema | ObjectSchema; 
} 

(code in playground)

Verwandte Themen