d3(v4)树的布局和打字稿:类型"HierarchyNode< IOrgChartNode>"上不存在属性"x" [英] d3 (v4) tree layout and typescript: Property 'x' does not exist on type 'HierarchyNode<IOrgChartNode>'
问题描述
我正在尝试使用具有树形布局的d3.hierarchy
根目录时使用适当的ts类型,例如:
I am trying to use proper ts types while using a d3.hierarchy
root with a tree layout, e.g.:
interface MyCustomGraphType {
id: string;
children?: MyCustomGraphType[]
}
let treeData: MyCustomGraphType = {/*...*/};
let root = d3.hierarchy(treeData);
let layout = d3.tree().size([500,500])(root);
let nodes = layout.descendants();
// BIND DATA (Node)
let node = this.nodesGroup.selectAll('g.node')
.data(nodes, d => d.data.person.email); // <--- compile-time error
// ^^^ Property 'data' does not exist on type '{} | HierarchyNode<MyCustomGraphType>'.
// ... later:
node.enter()
.append('circle')
.attr('transform', d => `translate(${d.x}, ${d.y})`); // <--- compile-time error
// ^^^ Property 'y' does not exist on type '{} | HierarchyNode<MyCustomGraphType>'.
显然,第一个错误是因为无论出于何种原因,都会在key
函数中推断联合类型'{} | HierarchyNode<MyCustomGraphType>'
.第二个错误是由于d3.tree
添加了以前未在其中定义的属性.
Clearly the first error is because for whatever reason the union type '{} | HierarchyNode<MyCustomGraphType>'
is inferred in the key
function. The second error is due to the fact that d3.tree
adds properties that were previously not defined there.
在保持类型安全的情况下,有什么干净的方法来解决这个问题?
What's a clean way to approach this while keeping type-safety?
谢谢!
P.S.我正在使用d3版本4
P.S. I am using d3 version 4
推荐答案
这里发生了一些事情,应该可以立即解决:
There are a few things going on here, which should be readily resolvable:
(1)为了澄清,我假设您的实际数据结构更像这样:
(1) To clarify, I assume that your actual data structure is something more like this:
interface MyCustomGraphType {
id: string;
person: {
email: string;
/*Other Properties*/
};
children?: MyCustomGraphType[];
}
这将解释您使用selection.data(...)
键功能访问节点的person.email
属性.
This would explain your accessing the person.email
proprty of a node in the selection.data(...)
key function.
(2)D3定义广泛使用了泛型类型参数.在某些情况下,类型推断将很容易为他们服务.在其他情况下,无法轻易推断出它们.
(2) The D3 definitions make extensive use of generic type parameters. In some cases type inference will serve them up readily. In others, they cannot be readily inferred.
- 使用
d3.tree<MyCustomGraphType>().size([500,500])(root);
这将返回类型为HierarchyPointNode<MyCustomGraphType>
的树布局根点.暗示nodes
现在将是HierarchyPointNode<MyCustomGraphType>[]
数组.
d3-selection 模块中的 -
select
,selectAll
,append
和data
具有有关各种重载签名的泛型的广泛JSDoc注释.它们应该作为鼠标悬停提示或类似的代码编辑器(例如VS Code)提供.
- Use
d3.tree<MyCustomGraphType>().size([500,500])(root);
This will return a tree layout root point of typeHierarchyPointNode<MyCustomGraphType>
. By implicationnodes
will now be anHierarchyPointNode<MyCustomGraphType>[]
array. select
,selectAll
,append
anddata
from the d3-selection module have extensive JSDoc comments regarding the various overloaded signatures' generics. They should be available as mouseover hints or similar in the code editor (e.g. VS Code).
(3)data
方法中的键访问器调出错误的原因如下:键访问器用于匹配 old 和 new 数据条目.旧数据类型基于前面的selectAll(...)
语句.鉴于无法从基于字符串的选择器中推断出所选元素的通用类型及其旧"数据类型,因此必须显式设置它们.否则,旧"数据类型默认为{}
.这就是为什么您看到联合数据类型{} | HierarchyPointNode<MyCustomGraphType>
的原因.必须注意,所选元素的旧"数据类型在实际所选元素和密钥访问器之间是同步的.必要时,关键功能应具有处理极端情况的方法.
(3) The reason why the key accessor in the data
method call errors out, is as follows: The key accessor is used to match old and new data entries. The old data type is based on the preceding selectAll(...)
statement. Given that the generic types of the selected elements and their "old" data type cannot be inferred from a string-based selector, they must be set explicitly. Otherwise, the "old" data type defaults to {}
. That is why you see the union data type {} | HierarchyPointNode<MyCustomGraphType>
. Care must be taken that the "old" data type of the selected elements is in synch between the actual selected elements and the key accessor. The key function should have a way to handle edge cases, if needed.
(4)至于x
或y
缺少的属性,我似乎无法复制此问题.对我来说,它们以d
in
(4) As for the missing properties x
or y
, I do not seem to able to replicate this issue. For me they are present, as the data type of d
in
attr('transform', d => `translate(${d.x}, ${d.y})`)
正确推断为HierarchyPointNode<MyCustomGraphType>
.
希望这可以解释.
这篇关于d3(v4)树的布局和打字稿:类型"HierarchyNode< IOrgChartNode>"上不存在属性"x"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!