我正在尝试为 .data()
使用自定义键功能与 .selectAll()
D3 中的选择。但是,让它兼容 TypeScript 变得如此痛苦。
如果没有 key 函数,元素将不会被正确删除,因为默认情况下 D3 使用索引来检查更新。
所以,这里是 JavaScript 代码片段,按预期工作正常:
const circles = svg
.select("g")
.selectAll("circle")
.data(data, d => d.val);
用 尝试同样的方法 typescript ,
interface IData {
val: number;
}
尝试 1
const circles = svg
.select("g")
.selectAll("circle")
.data<IData>(data, (d) => d.val);
Object d is of type 'unknown'. TS2571
35 | .select("g")
36 | .selectAll("circle")
> 37 | .data<IData>(data, (d) => d.val);
尝试 2
const circles = svg
.select("g")
.selectAll<SVGSVGElement, IData>("circle")
.data<IData>(data, (d) => d.val);
No overload matches this call.
Overload 1 of 3, '(data: IData[], key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
Argument of type '(this: SVGSVGElement | Element | EnterElement | Document | Window | null, d: IData) => number' is not assignable to parameter of type 'ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string>'.
Type 'number' is not assignable to type 'string'.
Overload 2 of 3, '(data: ValueFn<BaseType, unknown, IData[]>, key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
Argument of type 'IData[]' is not assignable to parameter of type 'ValueFn<BaseType, unknown, IData[]>'.
Type 'IData[]' provides no match for the signature '(this: BaseType, datum: unknown, index: number, groups: BaseType[] | ArrayLike<BaseType>): IData[]'. TS2769
而且,如果没有数据的关键功能,一切都可以正常工作:
const circles = svg
.select("g")
.selectAll<SVGSVGElement, IData>("circle")
.data<IData>(data);
最佳答案
从docs可以看出关键函数需要返回一个字符串(强调我的):
A key function may be specified to control which datum is assigned to which element, replacing the default join-by-index, by computing a string identifier for each datum and element.
这也可以通过查看 type definitions 看出。为
selection.data()
:data<NewDatum>(data: NewDatum[], key?: ValueFn<GElement | PElement, Datum | NewDatum, string>): Selection<GElement, NewDatum, PElement, PDatum>;
这里的关键函数定义为
key?: ValueFn<GElement | PElement, Datum | NewDatum, string>
与
ValueFn
类型是export type ValueFn<T extends BaseType, Datum, Result> = (this: T, datum: Datum, index: number, groups: T[] | ArrayLike<T>) => Result;
看上面两个定义不难看出
Result
关键函数定义的 type 参数设置为 string,这是编译器错误的原因。从您的键函数返回一个字符串将解决这个问题:
.data(data, d => "" + d.val);
关于typescript - 如何使 data() 键函数与 TypeScript 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61040750/