D3.js类型错误排查:垂直柱状图构建时的TS2345报错问题
解决D3.js + TypeScript构建柱状图的TS2345错误
错误原因
TypeScript报错是因为d3.scaleBand的scale函数在传入不在定义域内的键时会返回undefined——尽管你的数据中period_ended_at已全部加入x轴定义域,但TypeScript无法静态推断这一点,因此判定返回值可能为number | undefined,而D3的.attr()方法不接受undefined作为属性值。
另外,d3.max在数据为空数组时会返回undefined,这也会导致y轴定义域的类型问题,间接影响后续y_scale的调用。
修复方案
1. 处理x轴scale的undefined返回值
调用x_scale时,用**非空断言运算符!**告知TypeScript该值一定存在,或提供默认值兜底:
// 非空断言(适用于确定数据都在定义域内的场景) .attr("x", (d) => x_scale(d.period_ended_at)!) // 或默认值写法(更安全) .attr("x", (d) => x_scale(d.period_ended_at) ?? 0)
2. 修复y轴定义域的潜在undefined问题
给d3.max添加默认值,确保定义域是有效的数值范围:
y_scale.domain([0, d3.max(data, (d) => d.price_cents) ?? 0]);
3. 可选:给scale添加类型标注
显式标注scale的输入输出类型,让TypeScript类型推断更精准:
const x_scale = d3.scaleBand<string>() // 指定输入为string类型 .range([0, width]) .padding(0.1); const y_scale = d3.scaleLinear<number, number>() // 指定输入输出为number类型 .range([height, 0]);
完整修复后的代码
type Analytics = { id: number; period_ended_at: string; price_cents: number; fee_cents: number; }; const data: Analytics[] = await get_data() const width = 600 const height = 400 const x_scale = d3.scaleBand<string>() .range([0, width]) .padding(0.1); const y_scale = d3.scaleLinear<number, number>() .range([height, 0]); const svg = d3.select(".chart") .append("svg") .attr("width", width) .attr("height", height) .style("border", "1px solid black") x_scale.domain(data.map((d) => d.period_ended_at)); y_scale.domain([0, d3.max(data, (d) => d.price_cents) ?? 0]); svg .selectAll("rect") .data(data) .join("rect") .attr("class", "bar") .attr("x", (d) => x_scale(d.period_ended_at)!) .attr("y", (d) => y_scale(d.price_cents)!) .attr("width", x_scale.bandwidth()) .attr("height", (d) => height - y_scale(d.price_cents)!);
内容的提问来源于stack exchange,提问作者SoupeChinoise
相关产品推荐
相关产品推荐

