3

I'm using the example D3 graph shown here. I have the following data object declared here:

interface ID3Data {
  age: string,
  population: number
}

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

and then being consumed in the following:

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

Which produces this error:

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

Since it's apparent that d3.pie().value() consumes a very specific type of input data, what am I doing wrong that's receiving the compilation error? Since D3's value function is specific to it's library... is it something that I can override in my typescript code?

1 Answer 1

2

This is the problematic code:

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

Since you did not specify the type of the data you are going to pass to the generator the TypeScript compiler will use the following type definition:

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

That results in the error you witnessed because your type ID3Data obviously does not match number | { valueOf(): number }.

Fortunately, this can easily be cured by using generics to pass the correct type of data while creating the generator:

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

This will have the compiler use the following type definition instead:

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

As you can see the type Datum is now passed on to the Pie interface type.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.