D3.js & Typescript 泛型 - selection.data() & K extends keyof T

D3.js & Typescript generics - selection.data() & K extends keyof T

更新 这里有一个 link to D3’s selection.data API, and a codesandbox 给你动手的类型。

目标 是拥有一个通用类型的接口,并在实现过程中传递一个 属性 键(也是通用的)以引用给定类型上的给定键。

我好像打字不对。

代码

我有一个具有两个属性的接口:

interface Props<T, K extends keyof T> {
  data: T[]
  dataKey: K
}

我尝试在我的函数中使用它:

const Heatmap = <T, K extends keyof T>({ data, dataKey }: Props<T, K>) => {
  …
  const svg = d3.select.<some other chained fns>

  // then later
  svg
   .append(‘g’)
   .selectAll(‘rect’)
   .data<T>(d => d[dataKey]) // problem code
}

编译器在数据回调下报错:

Argument of type '(this: SVGGElement, d: T) => T[K]' is not assignable to parameter of type 'T[] | Iterable<T> | ValueFn<SVGGElement, T, T[] | Iterable<T>>'.
  Type '(this: SVGGElement, d: T) => T[K]' is not assignable to type 'ValueFn<SVGGElement, T, T[] | Iterable<T>>'.
    Type 'T[K]' is not assignable to type 'T[] | Iterable<T>'.
      Type 'T[keyof T]' is not assignable to type 'T[] | Iterable<T>'.
        Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'T[] | Iterable<T>'.
          Type 'T[string]' is not assignable to type 'T[] | Iterable<T>'.
            Type 'T[string]' is not assignable to type 'T[]'.
              Type 'T[keyof T]' is not assignable to type 'T[]'.
                Type 'T[K]' is not assignable to type 'T[]'.
                  Type 'T[keyof T]' is not assignable to type 'T[]'.
                    Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'T[]'.
                      Type 'T[string]' is not assignable to type 'T[]'.ts(2345)

在 vanilla js 中,数据回调如下所示:

data(d => d.<key>)

我找遍了,没能拼凑起来。我使用 Record 实用程序摆弄了映射类型、索引类型,但我无法使其工作。我还尝试了可选的关键参数回调。似乎没有什么可以安抚 tsc。我在这里错过了什么?为什么这不像我写的那样有效?

FWIW,我这里的 typescript 代码确实可以在浏览器中运行,但是 tsc 无法编译

TIA

更新 下面的解决方案确实满足了编译器的要求,但只是表面上的。我发现从那以后,typescript 假设我正在传递一个字符串并抱怨很多。

最后的修复(到目前为止)是使用可选的 key ValueFn。声明文件不是很有用,但本质上,我能够将 .data() 调用更改为:

.data(data, () => xKey as string)

这之所以有效,是因为我使用了泛型并将密钥作为 props 传递给 React 组件,但也许这会对他们的旅程有所帮助。

下面是过时的解决方案

找到答案。它所需要的只是 return 一个字符串,la:

data(d => String(d[dataKey]))