[英]D3.js & Typescript generics - selection.data() & K extends keyof T
Update Here is a link to D3's selection.data
API, and a codesandbox for you hands on types.更新这里是 D3 的
selection.data
API的链接,以及供您动手操作的代码框。
The goal is to have a generically typed interface, and pass a property key (also generic) to reference the given key on the given type during implementation.目标是拥有一个通用类型的接口,并传递一个属性键(也是通用的)以在实现期间引用给定类型上的给定键。
I can't seem to get the typing right.我似乎无法正确输入。
The code代码
I have an interface with two properties:我有一个具有两个属性的接口:
interface Props<T, K extends keyof T> {
data: T[]
dataKey: K
}
I try to use this in my function:我尝试在我的 function 中使用它:
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
}
Compiler complains under the data callback:编译器在数据回调下报错:
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)
In vanilla js, the data callback looks like:在 vanilla js 中,数据回调看起来像:
data(d => d.<key>)
I have looked all over and could not manage to piece it together.我到处都看了看,无法拼凑起来。 I fiddled with mapped types, indexed types, using the Record utility, but I cannot make it work.
我使用 Record 实用程序摆弄了映射类型、索引类型,但我无法使其工作。 I also experimented with the optional key parameter callback.
我还尝试了可选的关键参数回调。 Nothing seems to appease
tsc
.似乎没有什么可以安抚
tsc
。 What am I missing here?我在这里错过了什么? Why doesn't this work as I wrote it?
为什么这不像我写的那样有效?
FWIW, the typescript code I have here does work in the browser, but tsc
won't compile FWIW,我这里的 typescript 代码在浏览器中确实有效,但
tsc
无法编译
TIA TIA
Update The solution below did indeed satisfy the compiler, but only superficially.更新下面的解决方案确实满足了编译器的要求,但只是表面上的。 I discovered that from then on, typescript assumed I was passing a string and complained a lot.
我发现从那时起,typescript 就认为我传递的是一个字符串并且抱怨很多。
The final fix (as yet) was to use the optional key ValueFn
.最后的修复(到目前为止)是使用可选
key ValueFn
。 The declaration files are not terribly helpful, but essentially, I was able to change the .data()
invocation to:声明文件不是很有用,但本质上,我能够将
.data()
调用更改为:
.data(data, () => xKey as string)
This only works because I'm using generics and passing the key as props to the react component, but maybe this will help someone along their journey.这只有效,因为我正在使用 generics 并将密钥作为道具传递给反应组件,但也许这会帮助他们的旅程。
Outdated solution below下面是过时的解决方案
Found the answer here .在这里找到了答案。 All it needed was to return a string, à la:
它所需要的只是返回一个字符串,就像:
data(d => String(d[dataKey]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.