jsonschema - Typescript-definitionsfil för json-objekt med stringattribut som typindikatorer
Jag undersöker skapandet av en Typescript Definitionsfil för Plotly.js. Jag har tittat på ett antal exempel på definitionsfiler i DefinitelyTyped-förvaret. En fråga som dyker upp är gränssnittet för Data-objektet. Data-objektet är en array av Traces, som visas i plot-schema.
Betrakta detta exempel på dataobjektet.
data = [
{
type: 'scatter',
x: [1, 2, 3],
y: [3, 1, 6],
marker: {
color: 'rgb(16, 32, 77)'
}
},
{
type: 'bar',
x: [1, 2, 3],
y: [3, 1, 6],
name: 'bar chart example'
}
];
Spårtyperna, såsom 'scatter' och 'bar', kan ha olika attribut. Till exempel har spårtypen 'pie' ett attribut som heter "direction".
Även om jag skulle vilja definiera separata gränssnitt för varje typ av spår, med gemensamma attribut samlade i ett högre nivå-gränssnitt, ser jag inget bra sätt att göra det på.
Det mest intuitiva tillvägagångssättet jag kan komma på är något liknande detta...
interface Trace {
x: Array<any>;
y: Array<any>;
}
interface BarTrace extends Trace {
type: 'bar';
// bar specific members
}
interface ScatterTrace extends Trace {
type: 'scatter';
// scatter specific members
}
Detta är inte giltig TypeScript. En typ förväntas, snarare än strängen 'bar' eller 'scatter'.
Är någon medveten om andra bibliotek med en liknande struktur som har TypeScript-definitioner, eller ett bättre sätt att strukturera TypeScript-definitionsfilen för denna JSON-struktur?
Svar #1
Jag tror att ditt bästa alternativ är att fortsätta som du gör, men definiera type som en sträng. Något liknande följande:
interface Trace {
type: string;
x: Array;
y: Array;
}
interface BarTrace extends Trace {
// bar specific members
}
interface ScatterTrace extends Trace {
// scatter specific members
}
let data: Array<Trace> = [
{
type: 'scatter',
x: [1, 2, 3],
y: [3, 1, 6],
marker: {
color: 'rgb(16, 32, 77)'
}
},
{
type: 'bar',
x: [1, 2, 3],
y: [3, 1, 6],
name: 'bar chart example'
}
];
När du har bestämt om type är "scatter" eller "bar" kan du konvertera variabeln på följande sätt.
data.forEach((item) => {
if (item.type === 'scatter') {
let trace: ScatterTrace = item;
// ...
} else {
let trace: BarTrace = item;
// ...
}
});
