使用D3.js进行打字稿打字

时间:2019-03-31 19:47:43

标签: javascript typescript d3.js

我使用的是here中显示的示例D3图。我在这里声明了以下数据对象:

interface ID3Data {
  age: string,
  population: number
}

const data: ID3Data[] = [
  { age: "<5", population: 2704659 },
  { age: "5-13", population: 4499890 }
]

,然后在以下消费:

const pie = d3.pie()
              .value(function(d: any) { return d.population; });

const arc = g.selectAll(".arc")
             .data(pie(data)) // ->>> Specifically this part of the code

哪个会产生此错误:

TypeScript error: Argument of type 'ID3Data[]' is not assignable to parameter of type '(number | { valueOf(): number; })[]'.
  Type 'ID3Data' is not assignable to type 'number | { valueOf(): number; }'.
    Type 'ID3Data' is not assignable to type '{ valueOf(): number; }'.
      Types of property 'valueOf' are incompatible.
        Type '() => Object' is not assignable to type '() => number'.
          Type 'Object' is not assignable to type 'number'.  TS2345

由于很明显d3.pie().value()消耗了非常特定类型的输入数据,因此我在做什么方面出错了,从而收到了编译错误?由于D3的value函数特定于它的库...我可以在打字稿代码中覆盖它吗?

1 个答案:

答案 0 :(得分:2)

这是有问题的代码:

const pie = d3.pie()
              .value(function(d: any) { return d.population; });

由于您未指定要传递给生成器的数据类型,因此TypeScript编译器将使用以下type definition

export function pie(): Pie<any, number | { valueOf(): number }>;

这会导致您看到错误,因为您的类型ID3Data显然与number | { valueOf(): number }不匹配。

幸运的是,可以在创建生成器时使用泛型传递正确的数据类型来轻松解决此问题:

const pie = d3.pie<ID3Data>()
  .value(function(d) { return d.population; });   // Do not use any for the parameter!

这将使编译器改为使用以下type definition

export function pie<Datum>(): Pie<any, Datum>;

如您所见,类型Datum现在传递给了Pie interface类型。