Angular5+TypeScript开发D3旭日图遇TS2339类型错误求助
解决Angular 5 + TypeScript构建d3-sunburst时的TS2339错误
嘿,我之前也碰到过类似的TypeScript和d3旭日图的类型问题,这些错误本质上都是TypeScript的类型检查在“较真”——它认不出d3给对象动态加上的属性,或者你没给数据明确的类型定义。下面给你逐个解决:
1. 搞定Property 'size' does not exist on type '{}'
这个错误一般是因为你给d3布局传的数据没有明确的类型,TypeScript不知道这个对象上有size属性。
解决起来很简单:
- 先给你的旭日图数据定义一个接口,把需要的属性都列出来:
interface SunburstNode { name: string; size?: number; children?: SunburstNode[]; } - 之后在处理数据的时候,把它指定为这个接口类型,比如用
d3.hierarchy处理数据时:const root: SunburstNode = d3.hierarchy(yourRawData) .sum(d => d.size);
这样TypeScript就明白d上确实有size属性了,不会再报错。
2. 解决Property 'x0'/'x1'/'y0' does not exist on type 'DefaultArcObject'
d3自带的DefaultArcObject类型只包含弧的基础属性,但旭日图的分区布局(比如d3.partition())会给节点动态加上x0、x1、y0、y1这些布局计算后的属性,默认类型里没有这些,所以TypeScript会报错。
这里有两种靠谱的解决方式:
方式一:自定义扩展类型(推荐)
自己创建一个新类型,继承默认的弧对象并加上需要的属性:
import { DefaultArcObject } from 'd3-shape'; interface SunburstArc extends DefaultArcObject { x0: number; x1: number; y0: number; y1: number; }
之后在使用弧生成器或者处理节点的时候,把类型指定为SunburstArc,比如:
const arcGenerator = d3.arc<SunburstArc>() .innerRadius(d => d.y0) .outerRadius(d => d.y1) .startAngle(d => d.x0) .endAngle(d => d.x1);
这种方式能保留TypeScript的类型检查优势,代码也更规范。
方式二:临时用类型断言(适合快速调试)
如果你只是想先跑通代码,不想定义新类型,可以用类型断言告诉TypeScript“我确定这个属性存在”:
.innerRadius(d => (d as any).y0) .outerRadius(d => (d as any).y1)
不过这种方式会关掉TypeScript对这些属性的检查,不建议长期用。
额外小提示
- 确保你装对了d3的类型定义包:运行
npm install @types/d3 --save-dev,注意Angular 5对应的d3版本可能比较旧,类型包的版本最好和你用的d3版本匹配,避免出现类型不兼容的问题。 - 如果你用
d3.partition()布局,还可以把布局的类型也关联起来,让类型检查更彻底:const partitionLayout = d3.partition<SunburstNode, SunburstArc>(); const nodes = partitionLayout(root);
内容的提问来源于stack exchange,提问作者Jithin Scaria
相关产品推荐
相关产品推荐

