D3,打字稿-类型'this'的参数不能分配给类型'BaseType'的参数 [英] D3, Typescript - Argument of type 'this' is not assignable to parameter of type 'BaseType'

查看:44
本文介绍了D3,打字稿-类型'this'的参数不能分配给类型'BaseType'的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有stackbiltz-https://stackblitz.com/edit/lable-line-break-vaszab?file=src/app/app.component.ts

I have stackbiltz here - https://stackblitz.com/edit/lable-line-break-vaszab?file=src/app/app.component.ts

我在Angular应用中有一个d3条形图.

I have a d3 bar chart in and Angular app.

使用创建z轴刻度的函数将x轴标签分为两行

The x axis labels are split onto two lines using a function that is called as the z axis ticks are created

private insertLinebreak(d) {

    let labels = d3.select(this);
    let words = d;
    console.log("Label:", labels.html());
    labels.text('');

    let index = words.indexOf(' ', words.indexOf(' ') + 1)
    let title = words.substr(0, index)
    let subtitle = words.substr(index + 1)

    let tspantitle = labels.append('tspan').text(title)
    let tspansubtitle = labels.append('tspan').text(subtitle)
    tspantitle
      .attr('x', 0)
      .attr('dy', '15')
      .attr('class', 'x-axis-title');
    tspansubtitle
      .attr('x', 0)
      .attr('dy', '16')
      .attr('class', 'x-axis-subtitle');

  };

该函数使用'this'选择调用该函数的'g'(但是在d3中,我认为它会选择整个svg)

The function uses 'this' to select the 'g' calling the function (but in d3 I think it selects the whole svg)

此代码可在stackblitz中使用,但在我的实际代码中却收到错误消息

This code works in stackblitz but in my actual code I get the error

Argument of type 'this' is not assignable to parameter of type 'BaseType'.

我知道这不是很有帮助

我认为这与Typescript及其处理"this"的方式有关

I think this hasbto do with Typescript and the way it handles 'this'

有人知道这是为什么发生的,我该如何解决.

Does anyone know why this is happening and how I can fix this.

推荐答案

编译器将 insertLinebreak()函数内的 this 类型推断为类StackedChartCompoent .查看类型定义对于 d3.select(node),但是,您可以看到它期望节点扩展 BaseType ,即

The compiler infers the type of this inside your insertLinebreak() function as your class StackedChartCompoent. Looking at the type definitions for d3.select(node), however, you can see that it expects the node to extend BaseType which is defined as

export type BaseType = Element | EnterElement | Document | Window | null;

因为您的课程显然没有扩展此 BaseType ,所以您收到了错误消息.

Because your class clearly does not extend this BaseType you got the error.

基本上有两种解决方法:

There are basically two ways around this:

  1. 如果仅在一个地方需要 insertLinebreak()方法,即作为对 .each()的回调,则可以使其成为函数表达式然后直接将其作为参数传递给 .each()

  1. If you need the insertLinebreak() method only at one place, namely as the callback to .each(), you can make it a function expression which is then passed directly as an argument to .each()

.each(function() {
  let labels = d3.select(this);   // works
  // ...the original method's body
})

之所以可行,是因为编译器现在知道此函数的单个入口点,并且可以推断 this 的类型,因为

This works because the compiler now knows the single entry point for this function and can infer the type of this since .each() uses Function.prototype.call() to bind this to the node.

请记住,您必须使用经典函数表达式来支持ES6箭头函数,因为这会使 this 再次指向其词法范围,而不是指向节点.

Keep in mind, though, that you have to use the classic function expression in favor of an ES6 arrow function because that would have this again point to its lexical scope instead of to the node.

幸运的是,TypeScript本身内置了一种更惯用的方式.由于 <代码>此参数作为函数的参数列表中的第一项.该参数告诉编译器此函数中的 this 指的是什么.因此,您的代码可以重写为:

Fortunately, there is a more idiomatic way built into TypeScript itself. Since version 2.0 you can provide a fake this parameter as the first item in your function's parameter list. This parameter tells the compiler what this is referring to inside of said function. Your code could thus be rewritten as:

private insertLinebreak(this: SVGTextElement) {
  let labels = d3.select(this);   // works
  // method body left untouched
}

这篇关于D3,打字稿-类型'this'的参数不能分配给类型'BaseType'的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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