Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d3 types don't match the version we're using #1900

Closed
jameshadfield opened this issue Nov 14, 2024 · 3 comments
Closed

d3 types don't match the version we're using #1900

jameshadfield opened this issue Nov 14, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@jameshadfield
Copy link
Member

jameshadfield commented Nov 14, 2024

I encountered this while fixing a specific bug in d3, but I suspect the problem is much more widespread within Auspice rather than just that described below, hence the broad issue title.

background

The d3-selection library we use to bind event listeners is version 1.4.2. Viewing past API docs for d3 libraries is difficult but the relevant docs (which match my testing) are these:

When a specified event is dispatched on a selected element, the specified listener will be evaluated for the element, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i]).

Because we define the listener as a fat-arrow function this is not rebound to the current DOM element and remains PhyloTree (PhyloTreeType).

types don't match reality
Changing the NodeCallback type to match reality, type NodeCallback = (this: PhyloTreeType, d: PhyloNode) => void causes a very interesting type error (we're using @types/d3-selection version 3.0.11):

src/components/tree/phyloTree/renderers.ts:146:18 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(typenames: string, listener: null): Selection<SVGPathElement, PhyloNode, SVGDefsElement, unknown> & ((this: SVGPathElement, event: any, d: PhyloNode) => void) & ((this: SVGPathElement, event: any, d: PhyloNode) => void)', gave the following error.
    Argument of type 'NodeCallback' is not assignable to parameter of type 'null'.
  Overload 2 of 3, '(typenames: string, listener: (this: SVGPathElement, event: any, d: PhyloNode) => void, options?: any): Selection<SVGPathElement, PhyloNode, SVGDefsElement, unknown> & ((this: SVGPathElement, event: any, d: PhyloNode) => void) & ((this: SVGPathElement, event: any, d: PhyloNode) => void)', gave the following error.
    Argument of type 'NodeCallback' is not assignable to parameter of type '(this: SVGPathElement, event: any, d: PhyloNode) => void'.
      The 'this' types of each signature are incompatible.
        Type 'SVGPathElement' is not assignable to type 'PhyloTreeType'.

Overload 2, (typenames: string, listener: (this: SVGPathElement, event: any, d: PhyloNode) => void, options?: any), is the signature of the current version of d3-selection, not the one we're using (note the first argument is event not the datum`). Overload 1 looks similarly wrong. I don't know why tsc doesn't show me overload 3.

So it seems the type definitions we are using don't match the d3 libraries we're using.

The types seemingly forbid far-arrow functions

The type definitions (regardless of the fact that they are for a different d3 version than we're using) look like they enforce this being what d3 sets it to via listener.call(this, ...); which essentially forbids the use of fat-arrow functions (as they inherit the this in scope where the function was called from). This seems very limiting - fat-arrow functions are very useful for just this reason!

@jameshadfield jameshadfield added the bug Something isn't working label Nov 14, 2024
joverlee521 added a commit that referenced this issue Nov 16, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
joverlee521 added a commit that referenced this issue Nov 19, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
joverlee521 added a commit that referenced this issue Nov 19, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
@victorlin
Copy link
Member

Thanks for the detailed write-up. I haven't fully wrapped my head around the fat-arrow function stuff, but I've opened PR #1913 to align the type versions.

@genehack
Copy link
Contributor

Thanks for the detailed write-up. I haven't fully wrapped my head around the fat-arrow function stuff

MDN has a good explanation of the "don't bind this" thing — there are times when this is actually useful, and then there are times when it turns around and bites you…

joverlee521 added a commit that referenced this issue Nov 22, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
joverlee521 added a commit that referenced this issue Nov 23, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
joverlee521 added a commit that referenced this issue Dec 7, 2024
Add types for most measurements specific files. I'm delaying converting
the measurementsD3.js file because the import of `event` from
d3-selection causes an error. This is likely due to the d3 types not
matching the version of d3-selection.¹

I decided to place the measurements JSON types in the same file as the
measurements state types so that it's easy to compare the data
structures before and after parsing.

There are many type errors that will be fixed in subsequent commits.

¹ <#1900>
@jameshadfield
Copy link
Member Author

I consider this closed by #1913. I suspect we'll run into issues as we expand our usage of TS because I deliberately used fat-arrow functions to allow this: PhyloTreeType, but when we actually run into issues we can re-open this issue or create a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants