Pixi.js: Aide recherchée : mise à jour de la conversion TypeScript

Créé le 1 févr. 2020  ·  24Commentaires  ·  Source: pixijs/pixi.js

Bonjour la communauté PixiJS,

Nous avons franchi une étape majeure dans la conversion de PixiJS en TypeScript en convertissant le noyau et toutes ses dépendances. Maintenant que nous avons surmonté cette difficulté, nous pouvons commencer avec le reste des packages qui dépendent de ce petit ensemble de packages de base.

Nous pourrions certainement utiliser l'aide des développeurs pour convertir le reste de ces packages. Si vous êtes intéressé par la conversion d'un package, veuillez m'indiquer lequel. Il existe quelques directives pour convertir les packages, que vous pouvez voir à partir des PR terminés existants.

Conversion de Gotchyas

  • Nous essayons de maintenir les JSDocs jusqu'à ce que tout soit terminé, puis de convertir en Typedoc et d'émettre des types par la suite. Nous vous demandons de maintenir les JSDocs et de vous assurer qu'ils sont toujours créés et affichés correctement via npm run docs
  • Veuillez utiliser git mv pour renommer les fichiers JS en TS, sinon nous perdrons l'historique Git. Certaines interfaces graphiques Git peuvent ne pas prendre en compte ces modifications.
  • Veuillez ne pas ajouter de modificateurs d'accès public aux méthodes ou membres internes uniquement, laissez l'accès indéfini dans ces cas.

Paquets

Pour réclamer un package, veuillez créer un brouillon PR pour celui-ci

  • [x] @pixi/accessibility #6379
  • [x] @pixi/app #6376
  • [x] @pixi/constants #6173
  • [x] @pixi/core #6340, #6373
  • [x] @pixi/display #6261, #6339, #6349, #6371
  • [x] @pixi/extract #6381
  • [x] @pixi/graphics #6352
  • [x] @pixi/interaction #6656
  • [x] @pixi/loaders #6385
  • [x] @pixi/math #6141
  • [x] @pixi/mesh-extras #6396
  • [x] @pixi/mesh #6382
  • [x] @pixi/mixin-cache-as-bitmap #6630
  • [x] @pixi/mixin-get-child-by-name #6621
  • [x] @pixi/mixin-get-global-position #6637
  • [x] @pixi/particles #6449
  • [x] @pixi/polyfill #6654, #6669
  • [x] @pixi/prepare #6481
  • [x] @pixi/runner #6164
  • [x] @pixi/settings #6315
  • [x] @pixi/sprite-animated #6397
  • [x] @pixi/sprite-tiling #6398
  • [x] @pixi/sprite #6375
  • [x] @pixi/spritesheet #6389
  • [x] @pixi/text-bitmap #6479
  • [x] @pixi/text #6390
  • [x] @pixi/ticker #6186
  • [x] @pixi/unsafe-eval #6655
  • [x] @pixi/utils #6262
  • [x] @pixi/canvas-display #6659
  • [x] @pixi/canvas-extract #6503
  • [x] @pixi/canvas-graphics #6663
  • [x] @pixi/canvas-mesh #6664
  • [x] @pixi/canvas-particles #6622
  • [x] @pixi/canvas-prepare #6657
  • [x] @pixi/canvas-renderer #6499
  • [x] @pixi/canvas-sprite-tiling #6665
  • [x] @pixi/canvas-sprite #6658
  • [x] @pixi/canvas-text #6666
  • [x] @pixi/filter-alpha #6383
  • [x] @pixi/filter-blur #6383
  • [x] @pixi/filter-color-matrix #6383
  • [x] @pixi/filter-displacement #6383
  • [x] @pixi/filter-fxaa #6383
  • [x] @pixi/filter-noise #6383

Liasses

  • [ ] pixi.js-legacy #6673 En cours @bigtimebuddy
  • [ ] pixi.js #6673 En cours @bigtimebuddy

Commentaire le plus utile

Je déteste apporter des modifications à l'API pour tenir compte des limitations de frappe, cela ne me convient tout simplement pas. Personnellement, je préfère utiliser n'importe lequel puis créer une nouvelle méthode. Avoir une si grande surface d'API est déjà un fardeau.

Tous les 24 commentaires

Plus de conseils:

  • Essayez de séparer tous les import supplémentaires (en fait son type d'importation) des importations existantes. Nous ajouterons import type lors du déploiement de la nouvelle version TS. Cependant, linter vous empêchera d'utiliser deux lignes de import du même module, c'est bien de les mélanger dans ce cas.

  • Vous pouvez utiliser à la fois les notations Array<X> et X[] , j'utilise généralement Array<X> pour les structures qui sont souvent poussées-sautées (c'est-à-dire les listes). X[] pour les choses qui ont une petite longueur fixe ou si la taille est décidée au même endroit où elles sont construites (tableau régulier).

  • Si le champ readonly est modifié uniquement dans destroy() - vous pouvez y utiliser la conversion any . S'il est utilisé ailleurs - supprimez readonly . Nous pouvons décider d'en faire un private field + readonly property plus tard.

Je pourrais faire @pixi-text ce week-end à moins que quelqu'un ne me devance.

note : @pixi-tiling aura PIXI.TilingSprite.from nuit impossible à faire dans TS. Nous pouvons simplement le déprécier.

Allez-y, @qtiki. Je serai en ligne ce week-end au cas où vous trouveriez des choses étranges.

Ok, @qtiki , votre choix sera réservé après l'envoi du projet de PR.
Merci!

D'accord. Le brouillon PR est le meilleur moyen de réclamer un package à convertir. Merci pour ton aide

Ok, @qtiki , votre choix sera réservé après l'envoi du projet de PR.
Merci!

J'ai ouvert le brouillon PR #6390. Je viens de renommer les fichiers .js en .ts pour avoir quelques modifications afin de pouvoir créer le PR. Je vais essayer de faire la conversion proprement dite ce week-end.

Certaines choses génériques que j'ai rencontrées lors de la conversion du package Text en TypeScript :

J'ai donc rencontré un problème fondamental avec les propriétés TypeScript. Il semble que TypeScript ne prend pas en charge différents types de propriété getter et setter : https://github.com/microsoft/TypeScript/issues/2521

Il y a des endroits dans les classes Text et TextStyle où cela serait un énorme avantage. Par exemple, fillStyle et stroke dans TextStyle acceptent un nombre qui est ensuite converti en chaîne, donc le getter ne doit pas renvoyer un type union avec un nombre. Maintenant qu'il renvoie un type d'union avec un nombre, je dois le caster pour pouvoir le transmettre à CanvasRenderingContext2D fillStyle .

De plus, la classe Text elle-même accepte un objet avec le style de texte, qui est ensuite passé à new TextStyle - ou une instance de TextStyle directement. De même ici, le getter renverra toujours une instance de TextStyle mais doit être typé avec le même type d'union que le setter. Cela entraînera donc des vérifications de type inutiles (ou casts) dans userland pour pouvoir appeler des méthodes de TextStyle.

Je ne sais pas vraiment quelle serait la meilleure solution à long terme, mais pour l'instant, je suppose que cela devra suffire.

Une autre chose que j'ai remarquée est qu'il y a pas mal de code qui réutilise des variables locales avec un type différent, ce qui ne fonctionne pas très bien avec TypeScript. Je ne voulais pas trop toucher au code existant, alors j'ai juste utilisé des types d'union et quelques moulages laids ici et là pour le faire compiler. Je suppose que ce genre de choses peut être amélioré avec le temps avec le principe du boy scout .

@qtiki
Pourquoi écrivez-vous des problèmes dans ce sujet au lieu de votre PR ?

@qtiki
Pourquoi écrivez-vous des problèmes dans ce sujet au lieu de votre PR ?

Je pense que ce sont des problèmes génériques que les gens rencontreront ailleurs avec la conversion TypeScript et pas seulement des problèmes spécifiques au package de texte. Le problème de propriété pour l'un est quelque chose qui est une question de conception fondamentale pour l'avenir s'ils doivent être typés correctement.

J'étudie le problème des setters et des getters TypeScript qui ne peuvent pas utiliser différents types depuis que je l'ai rencontré. Il semble que le problème soit très complexe et qu'il ne soit jamais "résolu". Voici donc ma suggestion de directive générale pour convertir ces types de propriétés en TypeScript :

Ceci est un exemple simplifié de ce que nous voulons : une propriété qui accepte string | number mais est stockée en interne (et renvoyée) sous la forme string . Naturellement, nous pourrions retourner la propriété sous la forme string | number mais cela signifierait que les utilisateurs de l'API seraient confrontés à des vérifications de type complètement inutiles.

class Foo {
    constructor() {
        this._bar = '';
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    get bar(): string {
        return this._bar;
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    set bar(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

Voici comment nous pouvons contourner ce problème :

class Foo {
    constructor() {
        this._bar = '';
    }

    // Return the strictest type possible in the getter.
    get bar(): string {
        return this._bar;
    }

    // Use the same strict type for the setter as the getter.
    set bar(value: string) {
        // Call the conversion function.
        this.setBar(value);
    }

    // Implement a separate conversion function that accepts all supported types.
    public setBar(value: number | string) {
        this._bar = value.toString();
    }

    private _bar: string;
}

De cette façon, l'utilisateur obtient le type correct lors de la lecture de la propriété. Les utilisateurs de TypeScript qui souhaitent attribuer un number à bar devront appeler la fonction de conversion setBar . Cependant, ce ne serait pas un changement radical pour les utilisateurs JavaScript existants puisque le setter de propriété appelle la fonction de conversion - ce qui signifie que le setter de propriété non typé accepte réellement les nombres.

Qu'en pensez-vous, est-ce que ça a du sens ? Je ne sais pas à quelle fréquence ce type de modèle est utilisé, mais au moins dans le package de texte, je l'ai rencontré plus d'une fois.

Je déteste apporter des modifications à l'API pour tenir compte des limitations de frappe, cela ne me convient tout simplement pas. Personnellement, je préfère utiliser n'importe lequel puis créer une nouvelle méthode. Avoir une si grande surface d'API est déjà un fardeau.

Je n'approuverai jamais les hacks avec la méthode set*, je suis d'accord avec @bigtimebuddy que le type any est plus convivial que la méthode set* .

Dans le cas présent, il est tout à fait acceptable de renvoyer le type (string | number) pour getter.

En fait, parfois setBar est une bonne idée à cause des problèmes d'héritage de set , mais a besoin de plus de symboles dans le préfixe, comme _$setBar() :) Pas dans ce cas cependant.

@qtiki merci d'avoir mis en évidence le problème, je l'ai rencontré plusieurs fois lorsque j'ai fabriqué pixijs ts fork pour mes projets de travail.

Oui, Text c'est de la douleur. Oui, il faut y réfléchir davantage.

Je suis d'accord que le setBar n'est pas la plus jolie solution. Pour être honnête, j'ai été assez surpris que TypeScript ne prenne pas en charge ce type de setters avec coercition de type. Juste un mot d'avertissement sur ce que cela signifie d'utiliser une frappe plus lâche ou même any pour ces propriétés en ce qui concerne le contrôle de flux de TypeScript :

class Foo {
    constructor() {
        this._bar = '';
    }

    get bar(): string | number {
        return this._bar;
    }

    set bar(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

const foo = new Foo();

// TypeScript's flow control will assume from now on that `bar` is a `number`
foo.bar = 42;

function add(a: number, b: number) {
    return a + b;
}

// Call to `add` shouldn't be allowed since the value in `bar` is actually a string
// This will print `4242` instead of `84`
console.log(add(foo.bar, 42));

Je pense qu'à long terme, l'option la plus propre serait d'aller avec quelque chose comme ça:

class Bar {
    constructor() {
        this._bar = '';
    }

    get(): string {
        return this._bar;
    }

    set(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

class Foo {
    constructor() {
        this.bar = new Bar();
    }

    public bar: Bar;
}

const foo = new Foo();
foo.bar.set(42);
console.log(foo.bar.get());

Ce type de set n'est pas sans précédent car c'est exactement la façon dont PIXI.Point est implémenté. Fondamentalement, toutes les API orientées utilisateur accepteraient probablement l'instance Bar "telle quelle" sans avoir à appeler manuellement le get partout.

Naturellement, ce serait un changement radical, donc pas quelque chose pour un avenir proche, je voulais juste mettre mes deux sous.

Et je viens de réaliser que ma suggestion précédente ne serait plus une propriété "réelle", donc des choses comme Object.assign ne fonctionneraient plus avec le setter. Donc peut-être pas la meilleure idée après tout.

Salut, je suis un utilisateur de longue date de PixiJS et de Typescript. Je serais en mesure d'y contribuer - Il semble que la plupart des packages aient été réalisés à ce stade. A part ceux en toile. Y a-t-il des personnes sur lesquelles je peux aider ?

@lloydevans oui !!! Envie de préparer ou de texte-bitmap ? Les deux sont de bons packages, espérons-le, pas super compliqués.

@bigtimebuddy Génial ! Je pourrais jeter un oeil à faire du texte-bitmap.

Ça a l'air bien! Veuillez faire un brouillon de PR une fois que vous avez commencé afin que nous puissions le suivre ici.

OK je le ferai. Je vais maintenant jeter un œil à certaines des conversions et relations publiques existantes et je ferai de même.

Il semble que les packages individuels dans npm n'aient toujours pas de types. Je suppose que c'est quelque chose qui peut être résolu une fois ce problème résolu? Ce serait formidable de pouvoir les utiliser pour réduire la taille des constructions sans sacrifier la sécurité des types.

Allongez-vous tous à la maison ! Il ne reste que quelques colis !

Un grand merci à @Zyie , @ivanpopelyshev , @SerG-Y, @eXponenta et tous les autres contributeurs qui ont rendu cette migration possible.

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