qkhanhpro
qkhanhpro

Reputation: 5220

Understanding Typescript definition

From the @types/d3 definition, we have the lines:

export type ValueFn<T extends BaseType, Datum, Result> = (this: T, datum: Datum, index: number, groups: T[] | ArrayLike<T>) => Result;

attrTween(name: string): ValueFn<GElement, Datum, (t: number) => string> | undefined;

When I use the function attrTween, I use it like so :

caller.attrTween("points", (d, index, groups) => { return (t) => {return "";};  }

In which caller is Transition<BaseType, PieArcDatum<number>

These parameters are inferred by VSCode as :

(parameter) d: d3.PieArcDatum<number>
(parameter) index: number
(parameter) groups: d3.BaseType[] | d3.ArrayLike<d3.BaseType>

How does type definition enforce this behaviour? Can It be explained word-by-word, especially the Generic usage?

Upvotes: 2

Views: 271

Answers (1)

Jeff Bowman
Jeff Bowman

Reputation: 95704

attrTween has three separate overloads, where the third entry (and only two-argument overload with a non-null second argument) is:

/**
 * Assign the attribute tween for the attribute with the specified name to the specified interpolator factory.
 * An interpolator factory is a function that returns an interpolator; when the transition starts, the factory is evaluated for each selected element.
 * The returned interpolator will then be invoked for each frame of the transition, in order,
 * being passed the eased time t, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the attribute value.
 * The interpolator must return a string.
 *
 * @param name Name of attribute.
 * @param factory An interpolator factory which is evaluated for each selected element, in order, being passed the current datum (d),
 * the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i]). The interpolator factory returns a string interpolator,
 * which takes as its argument eased time t, typically in the range [0, 1] and returns the interpolated string.
 */
attrTween(name: string, factory: ValueFn<GElement, Datum, (t: number) => string>): this;

This matches your call much better than the overload you listed. This definition exists in Transition, which is defined as the following:

export interface Transition<GElement extends BaseType, Datum, PElement extends BaseType, PDatum>

With this, we can see the direct mapping:

  • d is Datum, which from caller is d3.PieArcDatum<number>
  • index is number
  • groups is T[] | ArrayLike<T> where T extends BaseType.
    • Per attrTween's definition, T in ValueFn is the same as GElement in Transition.
    • GElement is BaseType per your callee.
    • Therefore T is BaseType, so groups is d3.BaseType[] | d3.ArrayLike<d3.BaseType> as you see it.

Upvotes: 2

Related Questions