8000 [types-2.0] Add d3-hexbin by heavenshell · Pull Request #12089 · DefinitelyTyped/DefinitelyTyped · GitHub
[go: up one dir, main page]

Skip to content

[types-2.0] Add d3-hexbin #12089

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

Merged
6 commits merged into from
Jan 6, 2017
Merged

Conversation

heavenshell
Copy link
Contributor

case 1. Add a new type definition.

  • checked compilation succeeds with --target es6 and --noImplicitAny options.
  • has correct naming convention
  • has a test file with the suffix of -tests.ts or -tests.tsx.

d3-hexbin is not exists. So we add type definition.

@dt-bot
Copy link
Member
dt-bot commented Oct 19, 2016

d3-hexbin/index.d.ts

Checklist

@vvakame vvakame added the @types label Oct 25, 2016
Copy link
Contributor
@tomwanzek tomwanzek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heavenshell Thanks a lot for contributing this definition to the D3 universe. 😄

Hope you are o.k. with a few changes to consider. They in essence suggest using the same pattern we have applied when writing the other definitions for D3. I.p. to use generics to control type-safety without becoming too restrictive on the one hand or overly permissive by simply using any.

This way, we keep developers on a consistent experience.

// Definitions by: UNCOVER TRUTH Inc. <https://github.com/uncovertruth/>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

interface Point {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to specify an interface for Point. A generic can and should be used on the generator interface (see below) and the generator factory factory hexbin() (see below as well).

This allows to enforce type-safety throughout and corresponds to the pattern we used in the other D3 module definitions.

There seems to be no need to restrict the generic by setting a extends reference type here. It is truly any, as long as coordinates for x and y can be somehow extracted. This includes the default of [number, number].

As a general note for naming interfaces and data types when writing D3 module definitions, because of the way D3 was conceived, I would recommend not to use very generic names like Point, but rather something like HexbinPoint. This avoids issues with cross-module naming conflicts, when exporting to the same d3 global for vanilla script use scenarios. Same practice we followed elsewhere, e.g. VoronoiPoint.

interface Point {
[id: string]: number | string
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be an additional interface for the bin(s) returned by the generator, when applied to the points.

I.e. something like:

export interface HexbinBin<T> extend
10000
s Array<T> {
   x: number;
   y: number;
}

This corresponds to the data type of an element in bin array returned by the applied generator, as per API

Each bin in the returned array is an array containing the bin’s points. Only non-empty bins are returned; empty bins without points are not included in the returned array. Each bin has these additional properties:

x - the x-coordinate of the center of the associated bin’s hexagon
y - the y-coordinate of the center of the associated bin’s hexagon

These x- and y-coordinates of the hexagon center can be used to render the hexagon at the appropriate location in conjunction with hexbin.hexagon.

[id: string]: number | string
}

export interface Hexbin {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface for the generator should be generisized to keep it general, but typesafe:

export interface Hexbin<T> {
 ...
}

Here T corresponds to the type of a data point, which can be general, as long as the developer specifies the x- and y-accessors to extract the respective coordinates.

The defaults would correspond to T : [number, number], but it could be anything like

interface CrazyT {
  point: {
    x: number,
    y: number
  };
  moreStuff: any;
}

* If either the x- or y-coordinate is NaN, the point is ignored and will
* not be in any of the returned bins.
*/
(hexbin: Array<[number, number]> | Array<Point>): any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function signature should be:
(points: T[]): HexbinBin<T>[]

I.e. the generic controls the input and the output of the returned bins array.

* of each point. The default value assumes each point is specified as
* a two-element array of numbers [x, y].
*/
x(_: any): Hexbin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This signature should be x(x: (d: T) => number): Hexbin<T>

This will ensure that the accessor function is type-safe with respect to the data type of the points being passed in, and returning a number.

* of each point. The default value assumes each point is specified as
* a two-element array of numbers [x, y].
*/
y(): (d?: any) => number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be y(): (d: T) => number; for type safety.

8000
* the width of each hexagon is radius × 2 × sin(π / 3)
* and the height of each hexagon radius × 3 / 2.
*/
radius(_: any): Hexbin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more restrictive: radius(radius: number): Hexbin<T>.

* If extent is specified, sets the hexbin generator’s extent to the
* specified bounds [[x0, y0], [x1, y1]] and returns the hexbin generator.
*/
extent(_: any): Hexbin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more restrictive: extent(extent: [[number, number], [number, number]]): Hexbin<T>;

*
* The extent defaults to [[0, 0], [1, 1]].
*/
extent(): Array<[number, number]>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using [[number, number], [number, number]] as the return type. This is what we have done everywhere else in D3 module definitions with extent.

/**
* Constructs a new default hexbin generator.
*/
export function hexbin(): Hexbin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using two signatures for the generator factory:

export function hexbin(): Hexbin<[number, number]>;
export function hexbin<T>(): Hexbin<T>;

The first one corresponds to the default behavior, where the x- and y-accessor expect a point to be passed in directly as coordinates.

The second allows the developed to control the generic type which is enforced throughout the Hexbin<T> generator and all its accessors and return types, like the HexbinBin<T>[].

@heavenshell
Copy link
Contributor Author

@tomwanzek
Thank you for reviewed my PR!
I'm not familiar with TS but I'll try to update!

@tomwanzek
Copy link
Contributor

@heavenshell no worries, if you take a look at the interface for Quadtree in d3-quadtree, it has a very similar shape compared to how Hexbin could be done. The respective definition lines are here.

I.e. it defines a generator interface with accessors for x- and y-coordinates. And it has a few overloaded factories to create a generator. There are some more than you would need, as the factory can take arguments.

If you have any other questions, don't hesitate. Cheers. T

@heavenshell
Copy link
Contributor Author

@tomwanzek
Hi, sorry for late response.
I adopted your review point to d3-hexbin.d.ts.
Some tests were failed to build.
https://gist.github.com/heavenshell/748f94b4171cd44e8774e85685f09715

These tests are ported from https://github.com/d3/d3-hexbin/blob/master/test/hexbin-test.js
Failed at x() and y().
IMO d3-hexbin.d.ts should pass this tests.

I'm really appreciated if you give me advices to help solove problems.
Thank you.

P.S.
I want to use d3-hexbin.d.ts like following.
https://gist.github.com/heavenshell/171f32b8fd3de01ace8a413513d42864

@tomwanzek
Copy link
Contributor

@heavenshell With a bit of luck, I can fit it in some time later today. Latest on the weekend.

Could you push a commit with the proposed changes to the definitions file to this PR. This should make it easier to use the review feature to comment on specific lines, if need be.

As for tests, bear mind that one of the design choices of DefinitelyTyped was that, tests are essentially shape tests only. I.e. they only validate that the test file and its related definitions compile without error, they do not emit or execute anything beyond that. So testing the shape is essentially typing the left and right-side of an assignment independently and checking that the assignment does not fail, same with arguments to functions/methods and their return values.

Use generics to control type-safety.
@heavenshell
Copy link
Contributor Author

@tomwanzek
Pushed!

they only validate that the test file and its related definitions compile without error, they do not emit or execute anything beyond that.

Yeah, right.
But I'm worried about coverage of d3-hexbin's spec(use-cases).
I think original tests are covered d3-hexbin use-cases.
So I just want compile similar tests(not a result of test, just a compile test file).
If test file are ok to compile, I think d3-hexbin.d.ts coverage use-cases too.
I think this means user can use d3-hexbin.d.ts safely because test file can compile.

Sorry I'm not a good at English. If you were confused it's so sorry 😢

@tomwanzek
Copy link
Contributor

Thanks for pushing the changes, I will look at it later. As for language, no concerns there... my Japanese is distinctly worse. Which is to say, non-existent. Now that is really sad 😉

@tomwanzek
Copy link
Contributor
tomwanzek commented Nov 21, 2016

I had a look at the definitions, and structurally they appear accurate. So it's really just down to completing the tests.

I am copying in a short snippet here that should shed some light on how to apply the definitions in the tests. Clearly, when writing "production code", some of the explicit typing of variables below might be just inferred from an assignment. However, this allows testing the shape using a compile only test.

The key to using the factory, the generator and the accessors, is illustrated by the use of the Point interface below, to specify the generic T. Note that, I tend to test chainability of setters by explicit reassignment for type-preservation checking, e.g. hb = hb.x(x);. Again, when writing actual code, one would simply chain, but here it is about testing that the return type is unchanged for an individual accessor. Otherwise, a return type could have been accidentally changed without failing compilation in the next method invoked in a chain. Hope this clarifies:

import * as d3Hexbin from 'd3-hexbin';

interface Point {
    x0: number;
    y0: number;
}

let hb: d3Hexbin.Hexbin<Point>;
let bins: d3Hexbin.HexbinBin<Point>[];

// Create generator =======================================

hb = d3Hexbin.hexbin<Point>();

// Configure generator =====================================

// x Accessor ----------------------------------------------

let x: (d:Point) => number;
x = function (d: Point) { return d.x0; };

// test setter
hb = hb.x(x);

// test getter
x = hb.x();

// y Accessor ----------------------------------------------

let y: (d:Point) => number;
y = function (d: Point) { return d.y0; };

// test setter
hb = hb.y(y);

// test getter
y = hb.y();

// Use generator ============================================

bins = hb([
    { x0: 0, y0: 0 }, { x0: 0, y0: 1 }, { x0: 0, y0: 2 },
    { x0: 1, y0: 0 }, { x0: 1, y0: 1 }, { x0: 1, y0: 2 },
    { x0: 2, y0: 0 }, { x0: 2, y0: 1 }, { x0: 2, y0: 2 }
]);

interface RemappedBin {
    binCoordinates: [number, number];
    points: Point[];
}

let remappedBins: Array<RemappedBin>;

remappedBins = bins.map(bin => {
    const x: number = bin.x; // x-coordinate of bin
    const y: number = bin.y; // y-coordinate of bin
    const pointsInBin: Point[] = bin.map(p => {
        const point: Point = p;
        return point;
    });
    const remapped: RemappedBin = {
        binCoordinates: [x, y],
        points: pointsInBin
    };
    return remapped;
});

EDIT: Updated code-snippet for remappedBins illustration (2016-11-21)

@@ -51,7 +52,7 @@ export interface Hexbin {
* of each point. The default value assumes each point is specified as
* a two-element array of numbers [x, y].
*/
x(_: any): Hexbin;
x(_: (d: T) => number): Hexbin<T>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor edit: change _ to x.

@heavenshell
Copy link
Contributor Author
heavenshell commented Nov 21, 2016

@tomwanzek
Thank you for suggesting me a nice snippet.
I'm bit a busy but I'll look into it 😄

@tomwanzek
Copy link
Contributor

Hey, whenever you're ready. Great that you picked up contributing d3-hexbin! T

@heavenshell
Copy link
Contributor Author

@tomwanzek
Hi, I updated tests.
Could you review it?

@tomwanzek
Copy link
Contributor

Not sure, if I get to it today. But I will try asap. Thx, T

@alexeagle alexeagle force-pushed the types-2.0 branch 2 times, most recently from eae5d89 to ec9eb4b Compare November 23, 2016 21:00
@herkulano
Copy link

@tomwanzek @heavenshell
Hi, I've created a d3-plugin sometime ago and after the upgrade to v4 module I created the index.d.ts with the definitions for typescript, similar to the ones you have for d3-hexbin:
https://github.com/herkulano/d3-hist2d/blob/master/index.d.ts

I really don't like the structure, it doesn't feel right that in typescript I need to use it as hist2d() or h2.hist2d() and in javascript I can use d3.hist2d().

It feels a lot better to override or merge the d3 namespace, but I don't know how. I tried a few approaches without success. Have you tried this approach also? Or you think that what you have defined is the best approach?

@tomwanzek
Copy link
Contributor

@heavenshell I have been working away on moving the initial batches of "core" D3 module definitions to support strictNullChecks, which was a todo for a sunny day 😉 As soon as I cleared them up, I will get back to this PR as well.

I had not checked this one for strictNullChecks and some of the new linting rules as well. So should be back on it shortly.

@herkulano Is your question on how to use it related to
(1) using your plug-in with a module loader (i.e. using import) or
(2) as a plain vanilla script which extends the d3 global?

@herkulano
Copy link

@tomwanzek thanks for coming back to me.

My question is not on how to use it, but rather on how to create the index.d.ts file so that the plugin can be used in a more "natural" d3 way, like any other d3 module, e.g., d3.color().

It's clear to me how it can be used in "(1) using your plug-in with a module loader (i.e. using import)". In the case of the d3-hist2d plugin/module, which also applies to d3-hexbin it's:

import { hist2d } from 'd3-hist2d';
hist2d().bins(10)
// OR
import * as h2 from 'd3-hist2d';
h2.hist2d().bins(10)

My point is that this feels wrong. With d3 v4 all parts of d3 are modules now, so third-party modules should be the same as d3 default modules, this is true in Javascript so it should also be true in Typescript. It's weird having to change the syntax to use it.

In the definition files we should override/merge the d3 namespace instead to achieve this, but unfortunately, I wasn't able to make it work by declaring the d3 namespace in the definition file.

So then overriding/merging the d3 namespace we could then use any plugin like this, or something similar to this:

import 'd3-hist2d';
d3.hist2d().bins(10)

@tomwanzek
Copy link
Contributor

There is a simple reason, why I asked the question regarding how you would like to use the plug-in.

Scenario 1: As import with module loader

My point is that this feels wrong. With d3 v4 all parts of d3 are modules now, so third-party modules should be the same as d3 default modules, this is true in Javascript so it should also be true in Typescript. It's weird having to change the syntax to use it.

When used as proper modules, all D3 modules are anonymous, so your module definitions already correspond to the way all other definitions are written. There is no magic glue d3 object that ties them all together when imported, unless you create one using a barrel. This approach is really down to the user of D3 and your plug-in and is simply the way D3 is structured now:

// d3-with-hist2d-bundle.ts

// re-export all the  "standard" d3-modules you require
// or simply use export * from 'd3' for the entire standard D3 bundle

export * from 'd3-array';
export * from 'd3-selection';
...
export * from 'd3-hist2d';

Then if you want to use it as a more "conventional" d3 object simply import from this barrel:

// whatever-module-imports-d3.ts
import * as d3 from './d3-with-hist2d-bundle';

let x = d3.hist2d(); // et voila

Scenario 2: As plain vanilla script

This is where you actually run into a typescript vs D3 restriction. D3 code was written in a way, that the created UMD modules all merge into the same d3 global when used as plain vanilla scripts.

Assuming, you are writing your module the same way and using Rollup the same way, your JS code will support the same behavior as the other D3 scripts.

Important aside: As a word of caution, avoid clashing with variables/methods/interface names already defined for d3 modules (or their corresponding definition files w.r.t. TypeScript.)

In principle, creating a definition file for a UMD module, can be accomplished by writing the definitions for the proper module and adding:

export as namespace d3;

The definition file for the standard D3 bundle actually does that.

The definition files for the individual modules do not. This is due to TypeScript Issue 9681. The full history of this discussion is also embedded in #9936.

The resolution to this problem can only be achieved with a workaround at the level of the project using the definitions.

Add a directory, e.g. typings in your project, within that directory create a sub-directory named d3.

In the d3 directory, instead of creating a barrel module as described in Scenario 1, create a definition file index.d.ts with the following content:

// index.d.ts

export as namespace d3;

// re-export all the  "standard" d3-modules you require

export * from 'd3-array';
export * from 'd3-selection';
...
export * from 'd3-hist2d';

Make sure you add the typings directory to the typeRoots configuration of your compilation context tsconfig.json.

This way, should you write a plain vanilla script in typescript, you should have access to the merged d3 global by including the compiler directive /// <reference types='d3' /> at the top of the script.

@herkulano
Copy link

@tomwanzek thank you so much for your patience and thorough answer, really appreciate it! 💯

@tomwanzek
Copy link
Contributor

@herkulano You're welcome, one more module in the ecosystem due to your work, so props to you!

Copy link
Contributor
@tomwanzek tomwanzek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a few specific comments and a broad general comment at the beginning of the test file to explain some reasoning for practices I adopted elsewhere.

Hope this helps. Apologies for the slight delay.

"module": "commonjs",
"target": "es6",
"noImplicitAny": true,
"strictNullChecks": false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use "strictNullChecks": true, based on a quick validation, your definitions should already be valid with this option enabled.

We have just started the complete validation/updating of the core D3 modules. So you are ahead of the curve.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll update to strictNullChecks: true

@@ -0,0 +1,138 @@
// Type definitions for D3JS d3-hexbin module v0.2.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the following first line for the header, as the tslint rules have recently become stricter on the header comments:

// Type definitions for D3JS d3-hexbin module 0.2

The "v" and the patch release number are no longer permissible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix it.

// Project: https://github.com/d3/d3-hexbin/
// Definitions by: UNCOVER TRUTH Inc. <https://github.com/uncovertruth/>, Tom Wanzek <https://github.com/tomwanzek>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is related to the changes to the first line of the header comments. It is purely optional and simply a convention I personally follow. After an empty line below the main header, I add in a comment indicating the full version number of the latest release I validated the definition against. I find it easier as a checkpoint when looking for new changes in the underlying module. This way I do not need to compare commit dates. I use the following comment:

// Last module patch version validated against: 0.2.1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll add your comment.

// Last module patch version validated against: 0.2.1

* used to determine which hexagonal bin to add the point.
* If either the x- or y-coordinate is NaN, the point is ignored and will
* not be in any of the returned bins.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to JSDoc comments:

 * @param points An array of data points to bin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix it.

* If radius is specified, a hexagon with the specified radius is returned;
* this is useful for area-encoded bivariate hexbins.
*
* @param {number} radius Radius number
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend not to specify the argument type, e.g. number here, in the @param statements within TypeScript/JSDoc. The main reason is ease of re-factoring. It's easily overlooked when using IDE functionality meant for refactoring, which does not touch the type in the comments.

When an argument is optional, I tend to briefly indicated it in the @param description, e.g. `An optional radius parameter to be used when generating the hexagon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, remove {number}.
@param radis An optional radius parameter to be used when generating the hexagon
is ok?

// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

export interface HexbinBin<T> extends Array<T> {
x: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explanatory comment for x:

/*
 * x-coordinate of the center of the associated bin’s hexagon.
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix it.


export interface HexbinBin<T> extends Array<T> {
x: number;
y: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explanatory comment for y:

/*
 * y-coordinate of the center of the associated bin’s hexagon.
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix it.

y: number;
}

export interface Hexbin<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSDoc comment for interface itself:

/**
 * A generator for hexagonal binning.
 *
 * Hexagonal binning is useful for aggregating “big” data into a coarse, “small” representation for display:
 * rather than render a scatterplot of tens of thousands of points, bin the points into hexagons and show the distribution using color or area.
 *
 * The generic corresponds to the data type of an element in the points array.
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix it.


{
// hexbin.hexagon(radius) uses the current bin radius if radius is null
let path: string = d3Hexbin.hexbin().hexagon(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing in null as the radius should now fail with strictNullChecks on. The definitions only allow number | undefined, radius being optional. Here there is no need to support null in the definitions, as it has no special meaning, like "removing a listener or accessor function and returning to default behavior".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmm, so do I need to remove this test?

@@ -0,0 +1,211 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general note, since the tests in DT are strictly "shape tests", there are a few patterns I tend to follow in the other D3 module definitions:

  • When defining variables/constants always explicitly type them with the expected type. I.e. let x : number = ... rather than let x = ... This way, tests will fail if the right-hand side does not meet the expectation. Otherwise, the definitions could appear internally consistent due to TypeScripts implicit type inference. The same holds for accessor functions to be tested as the return type of a getter.
  • Test each signature for each interface method
  • For a "setter" method signature always test the return type individually. Do not use consecutive chaining in shape tests. Otherwise, the test may not find edge cases where a return type is (accidentally) changed by one method, but the next chained method is also defined on it, e.g. a sub-type. Re-assigning to the object on which a setter was invoked is a quick check for chainability.
  • As in the case of hexbin(), there are sometimes generator factories, which make a default assumption about underlying data types (like each point is of type [number, number]), but allow for more general data structures. In this case by setting the generic T e.g. to type Point. Again, I would first define a variable with explicit type, like Hexbin<[number, number]> or Hexbin<Point>, then test the factory by assigning to those variables.
  • When there are accessors involved, like here for x and y, I tend to test against each of the typed generators I obtained from the factory.

One aspect, that is helpful is creating explicit tests for expected failure modes, e.g. assigning let x: d3Hexbin.Hexbin<Point> = d3Hexbin.hexbin();. Same for e.g. method signatures with accessor functions depending on a generic. The benefit is that it may catch some edge cases. Note that such tests can only be inspected by you when updating tests. As you should see compiler errors in your IDE right away. You will need to comment them out before committing, so the CI tests do not fail. I tend to do that by also appending a comment like // fails, argument type mismatch or something similar.

You can find examples of the latter e.g. in d3-selection.

@ghost ghost added the Revision requested label Dec 27, 2016
@ghost
Copy link
ghost commented Dec 30, 2016

@heavenshell could you respond to the review comments?

@ghost
Copy link
ghost commented Jan 6, 2017

@tomwanzek Merging this, you can make the changes you mentioned if you want to.

@ghost ghost merged commit 312f8fb into DefinitelyTyped:types-2.0 Jan 6, 2017
@heavenshell
Copy link
Contributor Author
heavenshell commented Jan 6, 2017

sorry for late response.
I'm glad to somebody fix review point, sorry for my misunderstanding review point.
I think d.ts file would be fine.

@ghost
Copy link
ghost commented Jan 6, 2017

@heavenshell Great! Please do that in a new pull request, though, and based on the master branch.

@heavenshell
Copy link
Contributor Author

@Andy-MS
Thx, I still don't understand few review points, but I'll try it.
It's very appriceated if @tomwanzek helps me 👍

@tomwanzek
Copy link
Contributor

Will do in a spare minute. Thx for the contribution and merge.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0