简体   繁体   English

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

[英]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.

相关问题 在 Typescript 中记录了什么<k extends keyof any, t>意思是?</k> - In Typescript what does Record<K extends keyof any, T> mean? 为什么 typescript 不能正确推断 T[K]<t extends person, k keyof t> 通用的?</t> - Why typescript does not properly infer T[K] with <T extends Person, K extends keyof T> generic? 使用TypeScript,我可以键入getProperty的固化版本吗<T, K extends keyof T> - With TypeScript, can I type a curried version of getProperty<T, K extends keyof T> 打字稿类型RequireSome <T, K extends keyof T> 从属性中删除未定义的AND null - Typescript type RequireSome<T, K extends keyof T> removing undefined AND null from properties Typescript有没有办法实例化一个Record<k, v> 通过通用分配 function<t> 其中:T 扩展了一个对象类型并且 K = keyof T?</t></k,> - Is there a way in Typescript to instantiate a Record<K, V> by assignment in a generic function<T> where: T extends an object-type and K = keyof T? 如何在通用类中编写“ K扩展keyof T”并使用K - How to write “K extends keyof T” in a generic class and use K then Typescript generics keyof 类型不匹配 - Typescript generics keyof doesn't match type Typescript泛型中的“不在keyof中” - "Not in keyof" in Typescript generics Typescript generics 和 keyof - Typescript generics and keyof 当 T 可以未定义时,如何键入“K 扩展 keyof T”? - How to type `K extends keyof T` when T can be undefined?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM