Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
666 views
in Technique[技术] by (71.8m points)

typescript - Type errors for d3js in Angular ( Latest )

I've noticed there are many type errors for d3js when using it with Angular(typescript). For example I can't get the following snippet to work

svg.call(d3.zoom().on('zoom', () => {
      g.attr('transform', d3.events.transform);
    }));

Throws

S2345: Argument of type 'ZoomBehavior<Element, unknown>' is not assignable to parameter of type '(selection: Selection<BaseType, unknown, HTMLElement, any>, ...args: any[]) => void'. ??Types of parameters 'selection' and 'selection' are incompatible. ????Type 'Selection<BaseType, unknown, HTMLElement, any>' is not assignable to type 'Selection<Element, unknown, any, any>'. ??????Types of property 'select' are incompatible. ????????Type '{ <DescElement extends BaseType>(selector: string): Selection<DescElement, unknown, HTMLElement, any>; <DescElement extends BaseType>(selector: null): Selection<null, undefined, HTMLElement, any>; <DescElement extends BaseType>(selector: ValueFn<...>): Selection<...>; }' is not assignable to type '{ <DescElement extends BaseType>(selector: string): Selection<DescElement, unknown, any, any>; <DescElement extends BaseType>(selector: null): Selection<null, undefined, any, any>; <DescElement extends BaseType>(selector: ValueFn<...>): Selection<...>; }'. ??????????Types of parameters 'selector' and 'selector' are incompatible. ????????????Types of parameters 'groups' and 'groups' are incompatible. ??????????????Type 'BaseType[] | ArrayLike<BaseType>' is not assignable to type 'Element[] | ArrayLike<Element>'. ????????????????Type 'BaseType[]' is not assignable to type 'Element[] | ArrayLike<Element>'. ??????????????????Type 'BaseType[]' is not assignable to type 'Element[]'. ????????????????????Type 'BaseType' is not assignable to type 'Element'. ??????????????????????Type 'null' is not assignable to type 'Element'.

Also, another error is that d3.events is undefined.

Any tips on how to get this working? There are multiple code samples that just don't work due to type errors. Even suppressing with @ts-ignore doesn't solve them.

UPDATE: After using the migrations guide from v5 to v6, the zoom handler doesn't throw any more errors

const zoom = d3.zoom().on('zoom', ({transform}, d) => {
   g.attr('transform', transform);
});

But there still is the type error when trying to call it like this

svg.call(zoom)
question from:https://stackoverflow.com/questions/66059904/type-errors-for-d3js-in-angular-latest

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

About 'd3.event is undefined':

If you get the type error that d3.event is undefined, but d3.event works when you run the application, this means that the @types/d3 package is in the version that matches d3 v6, while the d3 package itself is on d3 v5. This error happens because of the changes between d3 v5 and v6, which includes the removal of d3.event.

You can see the types versions in the npm page. They roughly match d3 versions, so the one you're looking for is @types/[email protected].

About the type error:

If you don't define the type of the selection, it defaults to Selection<BaseType, unknown, HTMLElement, any>. However, the d3.zoom defaults to ZoomBehavior<Element, unknown>. The issue is that typescript complains that BaseType and Element are not compatible.

To fix it, you can define the svg selection and the zoom with explicit generics:

const svg = d3.select<SVGSVGElement, unknown>(...);
const zoom = d3.zoom<SVGSVGElement, unknown>() [...];

svg.call(zoom);

The first line says you're selecting an SVGSVGElement (the type of the <svg> element) that has unknown datum. The second line says that the zoom will be called on a selection of SVGSVGElement that also has an unknown datum type.

Now the generics of both zoom and svg match, and the .call method will be compatile. Here is a codesandbox that demonstrates it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...