【问题标题】:Typescript definition file for json objects with string attributes as type indicators以字符串属性作为类型指示符的 json 对象的 Typescript 定义文件
【发布时间】:2015-12-19 02:56:55
【问题描述】:

我正在调查为 Plotly.js 创建一个 Typescript 定义文件。我查看了DefinitelyTyped 存储库中的一些示例定义文件。想到的一个问题是 Data 对象的接口。 Data 对象是一个 Traces 数组,如plot-schema 中所示。

考虑这个数据对象的例子。

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' 
    }
];

跟踪类型,例如“scatter”和“bar”,可以具有不同的属性。例如,“饼图”跟踪类型具有“方向”属性。

虽然我想为每种跟踪类型定义单独的接口,并将公共属性分解为更高级别的接口,但我没有看到这样做的好方法。

我能想到的最直观的方法是这样的......

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
}

这不是有效的打字稿。需要一个类型,而不是字符串 'bar' 或 'scatter'。

是否有人知道其他具有类似结构的库具有 typescript 定义,或者有更好的方法来构造这个 JSON 结构的 typescript 定义文件?

【问题讨论】:

  • type : 'path' | 'point' | 'polygon'; 放在父Trace 类型中会起作用吗?这不会将子类型修复为特定的字符串,但是为接口提供一个不会更改的固定实例属性无论如何在打字系统中并没有真正意义——该类型有一个名称(BarTraceScatterTrace ) 来标识它并且 type 属性做同样的事情。
  • 我会试试这个。我有一段时间没看它了。感谢您的建议。

标签: typescript jsonschema plotly definitelytyped


【解决方案1】:

我认为您最好的选择是照常进行,但将type 定义为字符串。类似于以下内容:

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' 
    }
];

一旦确定type 是“散点”还是“条形”,您可以按如下方式转换变量。

data.forEach((item) => {
    if (item.type === 'scatter') {
        let trace: ScatterTrace = item;
        // ...
    } else {
        let trace: BarTrace = item;
        // ...
    }
});

【讨论】:

  • 你也可以使用类似stackoverflow.com/a/22071913/227299的东西来代替字符串
  • 感谢@wjohnsto 的快速回复。除非有人有更好的建议,否则这看起来像是我会去的方向。
  • 感谢@Juan-Mendes 对琴弦的建议。
猜你喜欢
  • 2021-03-27
  • 2022-01-27
  • 2020-01-07
  • 2020-08-17
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
相关资源
最近更新 更多