Definitelytyped: [D3] Affiner les définitions/réduction de la dette technique

Créé le 13 févr. 2018  ·  45Commentaires  ·  Source: DefinitelyTyped/DefinitelyTyped

  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) les auteurs (voir Definitions by: dans index.d.ts ) afin qu'ils puissent répondre.

    • Auteurs : @tomwanzek @gustavderdrache @Ledragon

Je crée ce problème en tant que problème de suivi de remplacement pour #11365, #11365 et #17846.

Ce qui suit est un tableau pour suivre les améliorations/dettes techniques liées aux définitions du module D3.

  • JSDoc : commentaires JSDoc complets, y compris les paramètres et l'explication des génériques
  • strictNullChecks : Validé pour strictNullChecks et l'option du compilateur est définie sur true
  • strictFunctionTypes : Validé pour strictFunctionTypes et l'option du compilateur est définie sur true
  • TS 2.3 : La version minimale de TS 2.3 et les définitions utilisent les valeurs par défaut pour les génériques

| Définition| JSDoc | strictNullChecks | strictFunctionTypes | TS 2.3 |
| --- | --- | --- | --- | --- |
| d3 | N/A | 🔲 | 🔲 | ✅ |
| tableau d3 | 🔲 | ✅ | 🔲 | 🔲 |
| d3-axe | ✅ | ✅ | ✅ | ✅ |
| brosse d3 | ✅ | ✅ | 🔲 | 🔲 |
| accord d3 | ✅ | ✅ | 🔲 | 🔲 |
| d3-collection | ✅ | ✅ | ✅ | ✅ |
| d3-couleur | 🔲 | ✅ | ✅ | ✅ |
| d3-contour | ✅ | ✅ | ✅ | 🔲 |
| d3-expédition | ✅ | ✅ | ✅ | ✅ |
| d3-glisser | ✅ | ✅ | 🔲 | 🔲 |
| d3-dsv | ✅ | ✅ | 🔲 | 🔲 |
| d3-ease | ✅ | ✅ | 🔲 | 🔲 |
| d3-fetch | ✅ | ✅ | 🔲 | 🔲 |
| force d3 | ✅ | ✅ | 🔲 | 🔲 |
| format d3 | ✅ | ✅ | ✅ | ✅ |
| d3-géo | ✅ | ✅ | ✅ | ✅ |
| d3-hexbin | 🔲 | 🔲 | 🔲 | 🔲 |
| d3-hiérarchie | 🔲 | 🔲 | 🔲 | 🔲 |
| d3-interpoler | 🔲 | 🔲 | 🔲 | 🔲 |
| d3-chemin | ✅ | ✅ | 🔲 | 🔲 |
| d3-polygone | ✅ | ✅ | ✅ | ✅ |
| d3-quadtree | 🔲 | 🔲 | 🔲 | 🔲 |
| d3-file d'attente | ✅ | 🔲 | 🔲 | 🔲 |
| d3-aléatoire | ✅ | ✅ | 🔲 | 🔲 |
| d3-demande | 🔲 | 🔲 | 🔲 | 🔲 |
| d3-sankey | ✅ | ✅ | 🔲 | 🔲 |
| échelle d3 | ✅ | ✅ | 🔲 | 🔲 |
| d3-échelle-chromatique | ✅ | ✅ | 🔲 | 🔲 |
| sélection d3 | ✅ | ✅ | ✅ | 🔲 |
| d3-sélection-multi | ✅ | ✅ | 🔲 | 🔲 |
| forme d3 | ✅ | ✅ | 🔲 | 🔲 |
| temps d3 | ✅ | ✅ | 🔲 | 🔲 |
| format d3-heure | ✅ | ✅ | 🔲 | 🔲 |
| minuteur d3 | ✅ | 🔲 | 🔲 | 🔲 |
| d3-transition | ✅ | ✅ | 🔲 | 🔲 |
| d3-voronoï | ✅ | 🔲 | 🔲 | 🔲 |
| d3-zoom | ✅ | ✅ | 🔲 | 🔲 |

"En dehors" de la maintenance de l'équipe de base :

| module | JSDoc | strictNullChecks | strictFunctionTypes | TS 2.3 |
| --- | --- | --- | --- | --- |
| d3-hsv | ✅ | ✅ | ✅ | ✅ |

Commentaire le plus utile

@denisname 💯 @gustavderdrache @ledragon Merci pour tout le travail acharné de ces derniers temps. J'ai mis à jour le tableau de suivi, il est déjà tellement plus joli ! 'cause un joli tableau de suivi est ce que nous visons ici :sourire:

Tous les 45 commentaires

@gustavderdrache @Ledragon Ci-dessus, j'ai consolidé les quelques tâches en suspens pour compléter l'œuvre qui est l'ensemble des définitions D3.

Une question clé : voulons-nous mettre à niveau toutes les définitions de manière cohérente vers une contrainte TS > = 2,3 et, ce faisant, supprimer certaines des surcharges de fonctions/méthodes en utilisant des affectations par défaut pour les génériques ?
J'ai remarqué que (par inadvertance) certaines des définitions ont déjà la contrainte // TypeScript Version: 2.3 dans l'en-tête des définitions. Par exemple d3-geo , qui utilise les définitions geoJson . Ceux-ci utilisent déjà des valeurs génériques par défaut.

Vos réflexions à ce sujet seraient plus que bienvenues.

Comprenez cela, vous devez l'étudier

Si vous implémentez un minimum de TS 2.3, nous devrions également pouvoir utiliser le type object au lieu de any , le cas échéant. Livré avec TS 2.2. Si je me souviens bien, il y avait une poignée d'opportunités avec des interpolateurs d'objets et dans d3-collection.

Premières réflexions :

  • En raison du bogue de mémoire insuffisante que vous avez rencontré, ne devrions-nous pas appliquer la version 2.4 partout ?
  • J'ai une succursale avec strictNullChecks et strictFunctionTypes ici . Je vais le mettre à jour et soumettre un PR. Je pensais l'avoir fait, mais cela ne semble pas être le cas

Je dois me renseigner sur les génériques par défaut avant d'avoir un avis là-dessus :p

Avec TS 2.3, nous envisageons une version d'avril 2017.
TS 2.4 est sorti en juin 2017.

La grande question est donc : créons-nous des problèmes dans une partie importante ou négligeable/aucune de la base installée lorsque nous forçons un minimum de 2,4 (plutôt que 2,3) ?

Je suppose que l'un des défis supplémentaires est que nous n'avons pas de journal des modifications en soi pour signaler les changements potentiellement importants dans la façon dont les définitions D3 sont consommées. Et la déconnexion évidente, qu'un changement de rupture pourrait se produire dans une version mineure des définitions, car elles sont alignées sur le cycle de publication D3 sous-jacent.

@gustavderdrache Que pensez-vous de TS 2.4 comme nouveau minimum ?

Comme on le voit dans PR # 23654, nous semblons cascader rapidement lorsque nous passons à TS 2.4 (même s'il s'agit simplement d'imposer la contrainte pour le bien de DT sans utiliser aucune fonctionnalité de TS 2.4 comme les énumérations de chaînes).

Pour plus de clarté, conformément au nouveau PR # 23724, nous pouvons simplement utiliser TS 2.3. Pas besoin d'aller de l'avant avec TS 2.4 pour le moment.

@Ledragon Si vous souhaitez ouvrir le PR que vous aviez déjà en attente dans votre fork d3-geo local, nous pouvons alors cocher les cases ci-dessus.

En fait, je ne peux pas le faire tester localement... Je pense donc que je peux le soumettre, mais je ne pense pas qu'il passera les tests de travis. Je vais juste aller de l'avant et voir

23794 soumis - pas mon travail dont je suis le plus fier, voyons comment ça se passe...

D'accord, le problème est donc le suivant : les tests d3-geo échouent dans TS 2.3, j'ai donc essayé de définir la version sur 2.4. Cependant, d3 global est défini sur TS 2.3, donc cela ne fonctionne pas non plus. Des conseils sur la marche à suivre ?

Je regarderai le PR g3-geo et y mettrai tous les commentaires de révision pour les garder concentrés. Contrairement au bogue OoM que j'ai eu avec d3-collection , nous avons un bon message d'erreur avec lequel travailler 😄

Je viens de soumettre #24118 pour mettre à jour d3-contour vers 1.2.0
J'ai remarqué que les types d3-contour sont déjà dans TS2.3 et que strictNullChecks et strictFunctionTypes sont définis sur true :-)

Merci d'être resté au top de d3-contour , m'a fait remarquer que pour une raison étrange, je n'avais pas le repo sur "Watching". Ça a changé ! :le sourire:

Je regarderai le PR sous peu.

Je travaille sur l'axe d3 et le format d3. J'ai presque fini. Mais j'ai des questions...

Au format d3, je souhaite utiliser la même interface Numeric que dans le tableau d3 :

interface Numeric {
    valueOf(): number;
}

Mais en faisant cela, dans les définitions globales d3, j'ai logiquement l'erreur : Module 'd3-array' has already exported a member named 'Numeric'. Y a-t-il un endroit où mettre les types partagés pour les bibliothèques d3 ?

De plus, dans certaines définitions d3 (interpolation, échelle, forme), vous pouvez trouver le type d'union number | { valueOf(): number } . Est-ce { valueOf(): number } ne suffit pas ?

@denisname Merci d'avoir fait du bénévolat pour d3-axis , d3-format et plus tard d3-array !!!

A vos questions ci-dessus :

(1) Comme règle fondamentale pour écrire les définitions des modules d3-xxx , les définitions ne doivent jamais introduire de dépendances qui n'existent pas entre les modules D3 correspondants sous-jacents. Par exemple, d3-axis n'a aucune dépendance sur d3-array , par conséquent, le fichier de définition index.ts pour d3-axis ne doit pas importer de d3-array . Cela garantit un couplage lâche correspondant aux sources JS. Donc, en cas de doute, vérifiez la propriété dependencies du package.json d3-xxx-test.ts module D3 sous-jacent. pratique que nous avons suivie dans un certain nombre de packages pour les tests "d'intégration". C'est-à-dire qu'il peut n'y avoir aucune dépendance formelle entre deux packages, mais que les membres de l'un sont "naturellement" utilisés comme entrée pour l'autre. Par exemple, nous utilisons d3-selection dans un test en d3-chord pour nous assurer qu'un chemin d'accord peut être transmis sans problème à un sélecteur d'attributs de sélection._

(2) Vous avez raison, l'interface Numeric ne peut être redéclarée dans aucun autre module D3, qui ne peut pas importer depuis d3-array conformément à la règle (1).

(3) Est-ce { valueOf(): number } ne suffisent pas ? Techniquement, oui. Pratiquement, le type d'intersection, tout en ayant une certaine redondance, est déclarativement probablement plus clair pour beaucoup d'utilisateurs humains. C'est-à-dire qu'il montre que number est un type valide à première vue sans acrobaties mentales. :clin d'œil:

À propos de d3-color, pourquoi les prototype sont-ils tous commentés ? Cela a été fait dans ce commit par @tomwanzek.

Avec les prototypes en retrait, nous pourrions utiliser instanceof directement, sans avoir besoin d'une fonction de typeguard :

let cRGB: d3.RGBColor;
let cHSL: d3.HSLColor;

const c: d3.RGBColor | d3.HSLColor = d3.color("steelblue");

if (c instanceof d3.rgb) {
    cRGB = c;
} else {
    cHSL = c;
}

@denisname J'ai hésité à définir prototype dans le cadre de l'API publiée dans une interface, cela semble trop hacky.

Pour ce que je comprends de la spécification des gardes de type d'aujourd'hui. Ceci est maintenant considéré comme une _construction_ valide. Voir l'élément de liste :

Une garde de type de la forme x instanceof C , où x n'est pas de type Any, C est d'un sous-type du type global 'Function' et C a une propriété nommée 'prototype' [...]

Je voudrais proposer une version strictNullChecks de d3-color . Ce qui est juste un changement d'une ligne. Ce serait l'occasion d'ajouter prototype aussi.

D'après mes propres tests, vous avez besoin de la propriété prototype ou d'une déclaration new(): T pour instanceof pour affiner correctement le type. J'ai utilisé la variation new(): Color dans les typages v3, et cela pourrait être utile si cet idiome est toujours pris en charge par D3v4 et supérieur.

Comme l'un ou l'autre semble bien, je pense que nous pourrions suivre la convention v3 pour la continuité. Super boulot, tous les deux.

@gustavderdrache

Ma compréhension de la raison pour laquelle cela fonctionne dans d3 v3 est que le type de retour de new() est toujours le même que le type prototype . Mais en d3 v4 nous avons aussi :

export const color: ColorFactory;
export interface ColorFactory extends Function {
    (cssColorSpecifier: string): RGBColor | HSLColor;
    prototype: Color; // and not RGBColor | HSLColor !
}

En effet, d3.lab(0,0,0) instanceof d3.color est vrai. Par conséquent, si nous changeons cette interface en :

export const color: ColorFactory;
export interface ColorFactory extends Function {
    (cssColorSpecifier: string): RGBColor | HSLColor;
    new (cssColorSpecifier: string): RGBColor | HSLColor;
}

Nous n'avons pas comme prototype pour ColorFactory le type Color . Et le code suivant ne parvient pas à se compiler, alors qu'il ne le devrait pas.

declare let l: d3.LabColor | null;
declare let c: d3.Color;
declare let nil: null;

if (l instanceof d3.color) {
    c = l; // l is not inferred as `d3.LabColor`...
} else {
    nil = l; // fail, l is a `d3.LabColor | null` should be a `null`
}

Quel est ton opinion? Existe-t-il un moyen de le faire fonctionner avec new ? Merci.

Il semble que la propriété prototype pour color() devrait être Color et non RGBColor | HSLColor , d'après certains tests :

> d3.color.prototype === d3.rgb.prototype
false
> d3.rgb.prototype instanceof d3.color
true

La fonction color() renvoie les couleurs RVB ou TSL, mais son prototype est un supertype des autres espaces colorimétriques.

@denisname @Ledragon @gustavderdrache puisque vous êtes tous sur ce fil, tout comme un bref FYI : j'ai l'intention de rattraper les éléments ouverts dont vous êtes au courant ce week-end.

D'accord, d3-geo est sorti (merci @ledragon) et j'ai commenté le PR malheureusement fermé de @denisname pour d3-format et d3-axis concernant la réouverture.

En règle générale, je recommanderais que @denisname soit ajouté en tant qu'autre responsable des définitions sur lesquelles ils travaillent.

Je pourrais jeter un œil à d3-color ensuite, et le joindre avec une mise à jour vers 1.1.0 . Devrions-nous ouvrir un problème séparé pour cette mise à jour ?

Aussi, bienvenue à bord @denisname !

@Ledragon Merci.

J'ai une mise à jour prête pour d3-color (pas encore lhc et gray ). Je suis juste bloqué par un petit problème.

@gustavderdrache a dit :

La fonction color() renvoie des couleurs RVB ou TSL, mais son prototype est un supertype des autres espaces colorimétriques.

En effet et cela peut être _tapé_ facilement, voir la première interface dans mon commentaire . Mais @tomwanzek a proposé de n'utiliser que new() et d'éviter prototype . Je pense que dans ce cas particulier ce n'est pas possible. Non?...

Après avoir joué un peu plus, je vois le problème. Vous pouvez définir new(): Color dans l'interface ColorConstructor , mais cela ne couvre pas réellement la valeur de retour de la fonction :

declare namespace d3 {
  interface Color {
    // I forgot what was on the Color interface
    // This property exists just to make Color incompatible with {}
    __isColor: never;
    toString(): string;
  }

  interface RGBColor extends Color {
    r: number;
    g: number;
    b: number;
  }

  interface HSLColor extends Color {
    h: number;
    s: number;
    l: number;
  }

  interface LABColor extends Color {
    l: number;
    a: number;
    b: number;
  }

  interface ColorConstructor {
    (specifier: string): RGBColor | HSLColor;
    new(specifier: string): Color; // <- TS uses this for narrowing with instanceof
  }

  const color: ColorConstructor;
}

declare let l: d3.LABColor | null;
declare let c: d3.Color;
declare let nil: null;

if (l instanceof d3.color) {
  // Succeeds with l: d3.LABColor
  c = l;
} else {
  // Succeeds with l: null
  nil = l;
}

En conclusion : je pense que nous devons exposer la propriété prototype , car c'est vraiment le seul moyen de couvrir le comportement correct du constructeur et des tests instanceof :

  interface ColorConstructor {
    (specifier: string): RGBColor | HSLColor;
    new(specifier: string): RGBColor | HSLColor;

    readonly prototype: Color; 
  }

Désolé, pour le retard à revenir sur ce sujet. N'hésitez pas à utiliser prototype , à l'époque, c'était ma première impulsion à aborder également le instanceof . Cela "semblait" simplement hacky, mais comme c'est considéré comme une pratique acceptable, et si la continuité avec l'utilisation new() comme dans D3v3 n'est pas une option... Allons-y avec ce qui fonctionne !

@tomwanzek pourriez-vous mettre à jour le tableau de suivi.

Un ✅ doit être défini dans les colonnes strictNullChecks strictFunctionTypes et TS 2.3 pour les bibliothèques d3-axis , d3-color , d3-dispatch , d3-format , d3-polygon et d3-hsv .

De plus, un ✅ doit être défini dans la colonne JSDoc pour d3-dispatch , d3-polygon et d3-hsv .

Merci

Il y a une faute de frappe dans l'interface $ d3-geo GeoIdentityTranform . Il devrait être GeoIdentityTransform (avec un s ). Puis-je le corriger ? Des inquiétudes concernant la rétrocompatibilité ?

@denisname pour d3-geo s GeoIdentityTranform , je pense que nous pourrions faire ce qui suit :

  • Renommez l'interface mal orthographiée (Great catch!) (y compris son utilisation comme type de retour de geoIdentity()
  • Pour le moment ajouter
/**
 * <strong i="13">@deprecated</strong> Misspelled name. Use GeoIdentityTransform.
 */
export type GeoIdentityTranform = GeoIdentityTransform;
  • À un stade ultérieur, supprimez complètement le type mal orthographié.

@denisname 💯 @gustavderdrache @ledragon Merci pour tout le travail acharné de ces derniers temps. J'ai mis à jour le tableau de suivi, il est déjà tellement plus joli ! 'cause un joli tableau de suivi est ce que nous visons ici :sourire:

Parce qu'un joli tableau de suivi est ce que nous visons ici

Absolument! Les définitions de type améliorées ne sont qu'un effet secondaire agréable.

Certains d'entre vous travaillent-ils actuellement sur des définitions spécifiques pour compléter la dette technique ? Pendant que d3-array est en cours. Je m'attaquerais ensuite au strictFunctionTypes dans d3-transition pour l'amener à parité avec d3-selection . J'attends juste que #25805 soit fusionné.

Pas de guichet automatique. Je vous ferai savoir si et quand je le fais

Travailler sur #25582 pour pouvoir tamponner le bundle global 5.2.0

J'ai une mise à jour pour d3-hierarchy prête (strict et jsDoc).
Travaille également sur d3-dsv et d3-fetch (ts 2.3).

@denisname @tomwanzek @gustavderdrache
Devrions-nous nous concentrer sur cela ou sur la mise à jour de d3 vers la dernière version ? Nous avons maintenant 5 versions mineures de retard sur le package global (bien que tous les sous-packages soient prêts pour 5.2.0 je pense). Dois-je ouvrir un problème séparé pour suivre l'état global du colis ?

@Ledragon Je vais rattraper les PR ouverts ce soir et analyser toutes les définitions de module D3 pour la devise. S'il y a des décalages, je créerai un problème de suivi pour les mettre à niveau. En ce qui concerne les priorités, je conviens que la monnaie devrait avoir la priorité sur la réduction technique de la dette.

Désolé de polluer ce fil, je reviens maintenant à D3.js pour un nouveau projet .. et je me demandais si l'annotation TypeScript en ligne était envisagée pour D3?

/** <strong i="6">@type</strong> {SyncBailHook<Compilation>} */
shouldEmit: new SyncBailHook(["compilation"]),

Dans Webpack, ils ont commencé à l'utiliser pour vérifier JavaScript avec le compilateur TypeScript. Le gros avantage est que les définitions de typage vivent juste à côté du code réel.
https://github.com/webpack/webpack/blob/master/lib/Compiler.js#L51

Salut @phil-lgr
Il n'y a pas si longtemps, il y a eu une discussion sur le suivi des problèmes d3 , et il ne semblait pas être en tête de liste des priorités (c'est-à-dire que Mike Bostock a préféré se concentrer sur le développement de la bibliothèque elle-même plutôt que sur les dactylographies). Je n'arrive pas à trouver un lien vers le fil. Peut-être que la question peut être soulevée à nouveau grâce à ces nouvelles informations, mais je ne pense pas que cela se produise

@tomwanzek pourriez-vous mettre à jour le tableau de suivi.

Un ✅ doit être défini dans les colonnes strictNullChecks strictFunctionTypes et TS 2.3 pour les bibliothèques d3-array , d3-array , d3-dsv , d3-fetch , d3-hexbin , d3-hierarchy , d3-interpolate , d3-quadtree , d3-queue , d3-request , d3-timer et d3-voronoi .

De plus, un ✅ doit être défini dans la colonne JSDoc pour d3-color , d3-hexbin , d3-hierarchy , d3-interpolate et d3-quadtree .

Merci

Cette page vous a été utile?
0 / 5 - 0 notes