【问题标题】:d3 Selection merge error in TypeScript: Types of property 'merge' are incompatibleTypeScript 中的 d3 选择合并错误:属性“合并”的类型不兼容
【发布时间】:2021-04-26 00:26:10
【问题描述】:

我有这段代码可以为 D3 堆叠条形图执行 D3 进入/合并/退出模式。我正在尝试将其移植到 TypeScript 以确保类型安全并在合并操作中出现以下错误。

注意:此代码在 JavaScript 中运行良好。

以下代码的摘录,有关完整的最小可重现示例代码,请参阅托管在 TypeScript Playground 上的 (https://tsplay.dev/m3AdLw)。请注意,错误 TS(2345) 出现在两个使用 d3Selection.merge() 的地方。

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) 错误:

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)

【问题讨论】:

  • 请考虑修改此问题中的代码以构成minimal reproducible example,将其放入像The TypeScript Playground (link to code) 这样的独立IDE 时,可以清楚地说明您面临的问题。这将使那些想要帮助您的人立即着手解决问题,而无需首先重新创建它。它将使您得到的任何答案都可以针对定义明确的用例进行测试。
  • @jcalz - 我已经用一个最小的可重现示例更新了这个问题。
  • 嗯,那里还有很多其他错误,可能还有不相关的代码。您能否将其简化为一个 minimal 示例,其中唯一存在的问题是您要询问的问题?无论如何,对我来说,我知道 TypeScript,但并不真正了解 d3。如果您需要了解两者的人,那么希望这样的人会出现。否则,您可能希望尝试使示例代码尽可能集中,以便人们可以深入研究它而不会走错路。祝你好运!
  • @jcalz 你可能会看看这个版本:tsplay.dev/wOaVym。其他错误源于此合并操作,因此无论如何这都是错误的根源。看看你如何使用这个略读的版本

标签: javascript typescript d3.js


【解决方案1】:

这是 D3 类型库的一个已知问题。我使用一个简单的解决方法:

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

const mergedLayers = existingLayers.merge(appendedLayers);

这是TS Workbench的截图:

【讨论】:

  • Michael Rovinsky - 如果我执行appendedLayers: any,那么它可以让我进行合并,但我无法执行下一段代码,它仍然会在mergedLayers .attr('fill', d =&gt; colorScMkr(d.key)) .attr('stroke', 'white') 处给我错误。请参阅 (tsplay.dev/m3AdLw) 获取代码。
  • 同样的技巧解决了所有其他问题(对不起,longURL,所以不允许链接缩短)
  • 谢谢 Michael - 当您说“这是 D3 和 TypeScript 的一个已知问题”时,您是否有参考记录在某处记录的任何票证/问题,与此相比,该问题正在被跟踪以获得正确的解决方案解决方法?在很多地方使用 any 是我在将代码库迁移到 TypeScript 时试图避免的事情
  • @ranaalisaeed 一个月前我问了一个类似的问题,但没有得到很好的答案:stackoverflow.com/questions/66762711/…。我还搜索了其他来源,并在 D3 存储库中看到了类似的票证而没有任何回应……我想 D3 的人不关心 TypeScript……我也是 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 2017-09-10
  • 2020-07-31
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多