类型'string |的参数不能将'null'分配给'ValueFn< SVGPathElement,Datum [],string |编号|布尔| null>' [英] Argument of type 'string | null' is not assignable to parameter of type 'ValueFn<SVGPathElement, Datum[], string | number | boolean | null>'
问题描述
我是d3的新手,并尝试使用d3,TypeScript和react来实现最小折线图.但这总是会导致TypeScript错误.在被错误消息替换之前,我什至在瞬间就看到了图表.
I am new to d3 and tried to implement a minimal line chart using d3, TypeScript and react. But it will always result in a TypeScript error. I even see my chart for a split second before it gets replaced by the error message.
我尽可能地将d3部分与反应代码分开.有一个react组件,用id
渲染div
,在componentDidUpdate
处,id
传递给包含我所有d3代码(下面的代码)的单独文件中的draw
函数.
我尝试为所有可以键入的内容提供一种类型.
I separated the d3 part from the react code as much as possible. There is a react component that renders a div
with an id
and at componentDidUpdate
the id
gets passed to a draw
function in a separate file with all my d3 code (code below).
I tried to provide a type for everything that can be typed.
import * as d3 from 'd3'
type Props = { id: string }
type Datum = {x: number, y: number}
type Data = Array<Datum>
const draw = (props: Props) => {
const data = [
{ x: 1, y: 5 },
{ x: 20, y: 20 },
{ x: 40, y: 10 },
{ x: 60, y: 40 },
{ x: 80, y: 5 },
{ x: 100, y: 60 },
]
const container = d3.select<HTMLElement, any>('#' + props.id)
container.selectAll<HTMLElement, any>('*').remove()
const svg = container.append<SVGElement>('svg')
const lineGenerator = d3.line<Datum>()
.x((d: Datum) => d.x)
.y((d: Datum) => d.y)
svg.append<SVGPathElement>('path')
.datum<Data>(data)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1.5)
.attr('d', lineGenerator(data))
}
export default draw
就像我说的那样,该图表是可见的,但很快消失了,反而我得到了:
Like I said, the chart is visible but quickly disappears and instead I get:
...
...中的TypeScript错误:
类型'string |的参数不能将'null'分配给的参数 类型'ValueFn< SVGPathElement,Datum [],字符串|编号|布尔| null>".
类型'null'不能分配给类型 'ValueFn< SVGPathElement,Datum [],字符串|编号|布尔| null>". TS2345
...
TypeScript error in ... :
Argument of type 'string | null' is not assignable to parameter of type 'ValueFn<SVGPathElement, Datum[], string | number | boolean | null>'.
Type 'null' is not assignable to type 'ValueFn<SVGPathElement, Datum[], string | number | boolean | null>'. TS2345
26 | .attr('stroke', 'steelblue')
27 | .attr('stroke-width', 1.5)
> 28 | .attr('d', lineGenerator(data))
| ^
29 | }
30 |
31 | export default draw
argument of type string | null
的来源以及如何解决该错误的任何想法?
Any ideas where the argument of type string | null
comes from and how to fix that error?
由于事实证明与问题无关,所以为了清楚起见,我删除了反应代码.
Since it turned out not to be related to the problem, I removed the react code for the sake of clarity.
推荐答案
此问题与TypeScript等效,它时不时弹出各种JavaScript问题,在此情况下,开发人员会混淆在引用中传递函数与在C中调用该函数.就地传递其返回值.
This question is the TypeScript equivalent of various types of JavaScript questions that pop up every now and then where the developer confuses passing a function by reference with calling said function in situ whereby just passing its return value.
您实际上是通过执行lineGenerator(data)
来调用(即执行)行生成器的.从API docs 和
You are actually calling, i.e. executing, the line generator by doing lineGenerator(data)
. As you can see from the API docs and the type definitions this will return either a string or null:
export interface Line<Datum> {
(data: Datum[]): string | null;
//...
}
This does not match the signature of the .attr() method, though, which in this case expects a function to be passed as the second argument.
export interface Selection<GElement extends BaseType, Datum, PElement extends BaseType, PDatum> {
//...
attr(name: string, value: ValueFn<GElement, Datum, string | number | boolean | null>): this;
//...
}
解决方案是将生成器传递给.attr()
而不执行它:
The solution is to pass the generator to .attr()
without executing it:
.attr('d', lineGenerator)
然后,生成器将通过.attr()
的内部工作方式执行,并将绑定到所选内容的数据传递给该生成器.依次返回路径d
属性的路径定义字符串.
The generator will then be executed by the inner workings of .attr()
being passed the data bound to the selection. That, in turn, will return the path definition string for the d
attribute of the path.
这篇关于类型'string |的参数不能将'null'分配给'ValueFn< SVGPathElement,Datum [],string |编号|布尔| null>'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!