2017-06-22 6 views
0

Es gibt eine question on SO über das Erstellen eines Arrays mit verschiedenen Typen, aber ich möchte ein Array mit mehreren komplexen Typen erstellen. Die Antwort in der Frage zu verknüpften empfiehlt die Verwendung eines Union-Typ, aber ich glaube nicht, dass für eine komplexe Art genügen, wie typescript documentation sagtein Array mit mehreren komplexen Typen

If we have a value that has a union type, we can only access members that are common to all types in the union. 

ich eine Reihe von Reports erstellen möchten. Einige der Berichte haben jedoch voneinander verschiedene Eigenschaften und auch mehrere Gemeinsamkeiten. Ich mache mir Sorgen, wenn ich es so erstelle wie unten, dann könnte ich irgendwo im Code nicht auf die verschiedenen Eigenschaften der Unterberichte zugreifen können.

Was ist die empfohlene Methode zum Erstellen eines Arrays komplexer Typen in Typescript?

interface Reports extends Array<Report>{} 

interface Report { 
    id: number; 
    timestamp: number; 
    type: string; 
    subreport: SubReportA | SubReportB | SubReportC 
} 



interface SubReportA { 
values: [] 
} 
interface SubReportB { 
random_property: number; 
other_random_name: number; 
} 
interface SubReportC{ 
values: []; 
name: string; 
} 
+0

Sollte nicht 'SubReportA' usw. sein Subklassen von' SubReport', und dann haben Sie gerade 'subreport: Subreport'? –

+0

Können Sie ein Beispiel geben, wie Sie Ihr Array verwenden möchten? – Rodris

+0

@RodrigoPedrosa Karte darüber und rendern jedes Mitglied in einer Berichtskomponente in einer Liste. – Leahcim

Antwort

2

Das ist ein Anwendungsfall für discriminated unions wäre. Zunächst benötigen wir eine Basisschnittstelle für alle Arten von Unterberichten. Ich werde auch ein Unterscheidungsfeld kind hinzufügen, das nur bestimmte Werte annehmen kann, die in der Kompilierungszeit "A", "B" und "C" bekannt sind.

interface SubReport { 
    kind: "A" | "B" | "C"; 
} 

An diesem Punkt können wir unsere Schnittstellen geben Sie eine Stringliteral jeder machen:

interface SubReportA { 
    kind: "A"; 
    values: [] 
} 

interface SubReportB { 
    kind: "B"; 
    random_property: number; 
    other_random_name: number; 
} 

interface SubReportC{ 
    kind: "C"; 
    values: []; 
    name: string; 
} 

Die gleiche Argumentation auf den ursprünglichen Report Typen angewandt werden könnte, wenn es sein muss. Ich bin mir nicht sicher, ob das Feld "Typ" des Berichts ein Diskriminator sein soll, aber es kann auch in das Subreport-Objekt verschoben werden.

Wie im obigen Link erläutert, können Sie mit diskriminierten Verbindungen auch bestimmte Felder abrufen, nachdem Sie den Diskriminator getestet haben.

if (subreport.kind === 'B') { 
    console.log(subreport.random_property); 
} 
Verwandte Themen