ranaalisaeed
ranaalisaeed

Reputation: 353

d3 Selection merge error in TypeScript: Types of property 'merge' are incompatible

I have this code that does the D3 enter/merge/exit pattern for D3 Stacked Bar Chart. I'm trying to port this over to TypeScript for type safety and getting the following error in merge operation.

Note: this code works fine in JavaScript.

Excerpt of the code below, for full minimal reproducible example code see (https://tsplay.dev/m3AdLw) hosted on TypeScript Playground. Note that the error TS(2345) appears in two places where d3Selection.merge() is used.

import d3Selection, {Selection, ContainerElement} from 'd3-selection'

let chartGroup = d3Selection.select('.chart-group')

let existingLayers = chartGroup.selectAll('.layer')
  .data(dataLayout)

let appendedLayers = existingLayers
  .enter().append('g')
  .classed('layer', true)

let mergedLayers = existingLayers.merge(appendedLayers) // <== TS(2345) error

mergedLayers.exit().remove()
mergedLayers.selectAll('*').remove()
        
mergedLayers
  .attr('fill', d => colorScMkr(d.key))
  .attr('stroke', 'white')

TS(2345) error:

Argument of type 'Selection<SVGGElement, unknown, BaseType, unknown>' is not assignable to parameter of type 'Selection<BaseType, unknown, BaseType, unknown>'.
  Types of property 'merge' are incompatible.
    Type '(other: Selection<SVGGElement, unknown, BaseType, unknown>) => Selection<SVGGElement, unknown, BaseType, unknown>' is not assignable to type '(other: Selection<BaseType, unknown, BaseType, unknown>) => Selection<BaseType, unknown, BaseType, unknown>'.
      Types of parameters 'other' and 'other' are incompatible.
        Type 'Selection<BaseType, unknown, BaseType, unknown>' is not assignable to type 'Selection<SVGGElement, unknown, BaseType, unknown>'.
          Types of property 'select' are incompatible.
            Type '{ <DescElement extends import(".../node_modules/@types/d3-selection/index").BaseType>(selector: string): import(".../node_modules/@types/d3-selection/ind...' is not assignable to type '{ <DescElement extends import("...node_modules/@types/d3-selection/index").BaseType>(selector: string): import(".../node_modules/@types/d3-selection/ind...'. Two different types with this name exist, but they are unrelated.
              Types of parameters 'selector' and 'selector' are incompatible.
                Types of parameters 'groups' and 'groups' are incompatible.
                  Type 'BaseType[] | ArrayLike<BaseType>' is not assignable to type 'SVGGElement[] | ArrayLike<SVGGElement>'.
                    Type 'BaseType[]' is not assignable to type 'SVGGElement[] | ArrayLike<SVGGElement>'.
                      Type 'BaseType[]' is not assignable to type 'SVGGElement[]'.
                        Type 'BaseType' is not assignable to type 'SVGGElement'.ts(2345)

Upvotes: 1

Views: 718

Answers (1)

Michael Rovinsky
Michael Rovinsky

Reputation: 7210

It is a known problem with D3 type library. I use a simple work-around:

cost appendedLayers: any = existingLayers
  .enter().append('g')
  .classed('layer', true)

const mergedLayers = existingLayers.merge(appendedLayers);

Here is a screenshot from TS Workbench: enter image description here

Upvotes: 1

Related Questions