d3 v4 TypeScript types

11,498

Exactly where your problem is I do not see. This is possible:

let mySelection : d3.Selection<SVGElement, {}, HTMLElement, any> = d3.selectAll<SVGElement, {}>('#line');
function foo() : d3.Selection<SVGElement, {}, HTMLElement, any> {
  return mySelection.append<SVGElement>('g')
}
alert(foo().node().tagName)
Share:
11,498
Ozzah
Author by

Ozzah

Updated on June 13, 2022

Comments

  • Ozzah
    Ozzah almost 2 years

    I'm putting together a little d3 project and since it's quite complex, I wanted to use TypeScript to make some of the development a bit simpler and less error-prone.

    I'm using d3 v4. I think I was using the wrong type definition file before, but I didn't run into any problems for a long time until it eventually complained that d3 does not contain a definition for scaleLinear().

    I've since moved to what I believe is the correct definition file, which does have a definition for d3.scaleLinear(), however now a significant number of my variables have invalid types.

    Here are some examples:

    public SVGElement    : d3.Selection<SVGElement>;
    public SVGTitleArea  : d3.Selection<SVGGElement>;
    public SVGLegendArea : d3.Selection<SVGGElement>;
    public SVGXAxisArea  : d3.Selection<SVGGElement>;
    public SVGYAxisArea  : d3.Selection<SVGGElement>;
    public SVGChartArea  : d3.Selection<SVGGElement>;
    

    I used to create these like this:

    this.SVGElement = d3.Select("body").append("svg");
    this.SVGTitleArea = <d3.Selection<SVGGElement>>this.SVGElement.append("g");
    

    etc.

    I also have a number of functions that render different components of the graph:

    public RenderTitle() : d3.Selection<SVGGElement> {
      this.SVGTitleArea = <d3.Selection<SVGGElement>>this.SVGElement.append("g");
    
      // Do stuff here
    
      return this.SVGTitleArea;
    }
    

    Ever since moving to the probably-correct typings file, it now complains that the d3.Selection type expects 4 types:

    interface Selection<GElement extends Element | EnterElement | Window, Datum, PElement extends Element | EnterElement | Window, PDatum>
    

    Now, I know it's not ideal and I would prefer a stronger typing, but I've managed to at least fix the errors with respect to the variable definitions:

    public SVGElement    : d3.Selection<SVGElement, any, any, any>;
    public SVGTitleArea  : d3.Selection<SVGGElement, any, any, any>;
    public SVGLegendArea : d3.Selection<SVGGElement, any, any, any>;
    public SVGXAxisArea  : d3.Selection<SVGGElement, any, any, any>;
    public SVGYAxisArea  : d3.Selection<SVGGElement, any, any, any>;
    public SVGChartArea  : d3.Selection<SVGGElement, any, any, any>;
    

    But I can't do the same for the render functions:

    public RenderTitle() : d3.Selection<SVGGElement, any, any, any>
    

    I've tried hovering over the calls that create, for example, the <g> element to see exactly what the signature should be, but it actually gives the , any any any>.

    What is my best option here? Is there a simple way to fix these types? Should I just leave them all as any? Should I downgrade to d3 v3? Should I keep using v4 and abandon TypeScript?

    Thank you.