2016-07-12 8 views
1

Ich schreibe eine Deklarationsdatei für eine Bibliothek (chart.js). Ein neues Diagramm ist wie folgt aufgebaut:Einschränkungen für Kombinationen von Typ-Parameter bei der Verwendung von Generics

let chart = new Chart(ctx, { type: 'line', data: ..., options: ... }) 

, wo die Arten von Daten und Optionsfeldern auf dem Typfeld abhängig sind

Bei dem Versuch, dies zu modellieren, dachte ich, die Art des Objekts, wie ein modellieren Unionstyp. Dadurch kann ich angeben, welche Objekte an den Konstruktor übergeben werden können (String-Literaltypen für das Typfeld).

Die Daten und Optionen Felder sind jedoch als Eigenschaften aus der Klasse nach der Konstruktion zugänglich und da ich nicht verwenden kann die Typen der Felder des eingegangenen Objekts dachte ich stattdessen mit Generika.

Das Problem, das ich jetzt habe, ist, dass ich einen anderen Typparameter für jedes der Felder (Typ, Daten und Optionen) benötigen würde, aber die Arten von Daten und Optionen werden durch den Typ des Typfelds bestimmt (ein String-Literal), ist nicht irgendeine Kombination möglich. Gibt es eine Möglichkeit, nur bestimmte Kombinationen von Typparametern anstelle aller Kombinationen zuzulassen? zum Beispiel

let lineChart = new Chart<'line', LineChartData, LineChartOptions> // OK 
let barChart = new Chart<'bar', BarChartData, BarChartOptions> // OK 
let chart = new Chart<'line', BarChartData, LineChartOptions> // ERROR 

Antwort

1

Wenn ich Sie richtig verstehe, dann können Sie dies tun:

interface ChartType<Data, Options> { 
    type: "line" | "bar"; 
    data: Data[], 
    options: Options[]; 
} 

interface LineType extends ChartType<string, string> { 
    type: "line"; 
} 

interface BarType extends ChartType<number, number> { 
    type: "bar"; 
} 

class Chart<Data, Options> { 
    constructor(ctx: any, type: LineType | BarType) { ... } 
} 

new Chart("ctx", { type: "line", data: [""], options: [] }); // ok 
new Chart("ctx", { type: "bar", data: [98], options: [9] }); // ok 
new Chart("ctx", { type: "line", data: [""], options: [3] }); // error 
new Chart("ctx", { type: "ha?", data: [], options: [3] }); // error 

(code in playground)

Ersetzen Sie einfach meine string und number mit Ihren Daten/Optionen Typen.

Verwandte Themen