类型'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>'

查看:143
本文介绍了类型'string |的参数不能将'null'分配给'ValueFn< SVGPathElement,Datum [],string |编号|布尔| 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&lt; SVGPathElement,Datum [],string |编号|布尔| null&gt;'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆