Pixi.js: Se busca ayuda: actualización de conversión de TypeScript

Creado en 1 feb. 2020  ·  24Comentarios  ·  Fuente: pixijs/pixi.js

Hola comunidad PixiJS,

Hemos alcanzado un hito importante en la conversión de PixiJS a TypeScript al convertir el núcleo y todas sus dependencias. Ahora que hemos superado este obstáculo, podemos comenzar con el resto de los paquetes que dependen de este pequeño conjunto de paquetes principales.

Definitivamente podríamos usar una mano de los desarrolladores para convertir el resto de estos paquetes. Si está interesado en convertir un paquete, hágame saber cuál. Hay algunas pautas para convertir paquetes, que puede ver en los PR completados existentes.

Convirtiendo Gotchyas

  • Estamos tratando de mantener los JSDocs hasta que todo esté completo, y luego convertirlos a Typedoc y emitir tipos después. Le pedimos que mantenga JSDocs y se asegure de que todavía se compilan y se muestran correctamente a través npm run docs
  • Utilice git mv para cambiar el nombre de los archivos JS a TS, o perderemos el historial de Git. Es posible que algunas GUI de Git no detecten estos cambios.
  • No agregue public modificadores de acceso a métodos o miembros solo internos, deje el acceso sin definir en estos casos.

Paquetes

Para reclamar un paquete, cree Borrador PR para él

  • [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

manojos

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

Comentario más útil

Odio hacer cambios en la API para acomodar las limitaciones de escritura, simplemente no me parece bien. Personalmente, prefiero usar cualquiera y luego crear un nuevo método. Tener una superficie API tan grande ya es una carga.

Todos 24 comentarios

Mas consejos:

  • Intente poner todos los import adicionales (en realidad, su tipo de importación) separados de las importaciones existentes. Agregaremos import type cuando se lance la nueva versión de TS. Sin embargo, linter evitará que use dos líneas de import del mismo módulo, está bien mezclarlas en ese caso.

  • Puede usar las notaciones Array<X> y X[] , normalmente uso Array<X> para las estructuras que se insertan con frecuencia (también conocidas como Listas). X[] para cosas que tienen una longitud pequeña fija o si el tamaño se decide en el mismo lugar donde se construyen (matriz regular).

  • Si el campo readonly se cambia solo en destroy() , puede usar la conversión any allí. Si se usa en otro lugar, elimine readonly . Podemos decidir si convertirlo en private field + readonly property más tarde.

Podría ganar @pixi-text este fin de semana a menos que alguien se me adelante.

nota: @pixi-tiling tendrá PIXI.TilingSprite.from qué noche no es posible hacer en TS. Podemos desaprobarlo.

Adelante, @qtiki. Estaré en línea el fin de semana en caso de que encuentres cosas raras.

Ok, @qtiki , tu elección se reservará después de enviar el borrador de relaciones públicas.
¡Gracias!

Acordado. Draft PR es la mejor manera de reclamar un paquete para convertir. Gracias por ayudar

Ok, @qtiki , tu elección se reservará después de enviar el borrador de relaciones públicas.
¡Gracias!

Abrí el borrador PR #6390. Acabo de cambiar el nombre de los archivos .js a .ts para tener algunos cambios y poder crear el PR. Intentaré hacer la conversión real este fin de semana.

Algunas cosas genéricas con las que me he encontrado al convertir el paquete de texto a TypeScript:

Así que me encontré con un problema fundamental con las propiedades de TypeScript. Parece que TypeScript no admite diferentes tipos para obtener y establecer propiedades: https://github.com/microsoft/TypeScript/issues/2521

Hay algunos lugares en las clases Text y TextStyle donde esto sería un gran beneficio. Por ejemplo fillStyle y stroke en TextStyle aceptan un número que luego se convierte en una cadena, por lo que el captador no debería devolver un tipo de unión con un número. Ahora que devuelve un tipo de unión con un número, tengo que convertirlo para poder pasarlo a CanvasRenderingContext2D fillStyle .

Además, la clase Text en sí misma acepta un objeto con el estilo de texto, que luego se pasa a new TextStyle , o una instancia de TextStyle directamente. De manera similar, aquí el getter siempre devolverá una instancia de TextStyle pero debe escribirse con el mismo tipo de unión que el setter. Por lo tanto, esto provocará algunas comprobaciones de tipo (o conversiones) innecesarias en el espacio del usuario para poder llamar a los métodos de TextStyle.

Realmente no sé cuál sería la mejor solución para esto a largo plazo, pero por ahora supongo que será suficiente.

Otra cosa que noté es que hay bastante código que reutiliza variables locales con diferentes tipos, lo que no funciona muy bien con TypeScript. No quería tocar demasiado el código existente, así que solo usé tipos de unión y algunos casting feos aquí y allá para compilarlo. Supongo que ese tipo de cosas se pueden mejorar con el tiempo con el principio de los boy scouts .

@qtiki
¿Por qué escribe problemas en este tema en lugar de su PR?

@qtiki
¿Por qué escribe problemas en este tema en lugar de su PR?

Creo que estos son problemas genéricos con los que las personas se encontrarán en otros lugares con la conversión de TypeScript y no solo problemas específicos del paquete de texto. El problema de la propiedad para uno es algo que es una cuestión de diseño fundamental para el futuro si se van a escribir correctamente.

He estado estudiando el problema con los setters y getters de TypeScript que no pueden usar diferentes tipos desde que me encontré con él. Parece que el problema es muy complejo y es posible que nunca se "solucione". Así que aquí está mi sugerencia de una guía general para convertir este tipo de propiedades a TypeScript:

Este es un ejemplo simplificado de lo que queremos: una propiedad que acepte string | number pero que se almacene internamente (y se devuelva) como string . Naturalmente, podríamos devolver la propiedad como string | number pero eso significaría que los usuarios de la API se enfrentarían a comprobaciones de tipos completamente innecesarias.

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;
}

Así es como podemos solucionar esto:

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 esta forma, el usuario obtiene el tipo correcto al leer la propiedad. Los usuarios de TypeScript que deseen asignar number a bar deberán llamar a la función de conversión setBar . Sin embargo, esto no sería un cambio importante para los usuarios de JavaScript existentes, ya que el definidor de propiedades llama a la función de conversión, lo que significa que el definidor de propiedades sin tipo acepta números.

¿Qué piensan ustedes, esto tiene sentido? No estoy seguro de con qué frecuencia se usa este tipo de patrón, pero al menos en el paquete de texto lo encontré más de una vez.

Odio hacer cambios en la API para acomodar las limitaciones de escritura, simplemente no me parece bien. Personalmente, prefiero usar cualquiera y luego crear un nuevo método. Tener una superficie API tan grande ya es una carga.

Nunca aprobaré hacks con el método set*, estoy de acuerdo con @bigtimebuddy en que el tipo any es más amigable que el método set* .

En el caso actual, es bastante aceptable el tipo return (string | number) para getter.

En realidad, a veces setBar es una buena idea debido a los problemas de herencia de set , pero necesita más símbolos en el prefijo, como _$setBar() :) Aunque no en este caso.

@qtiki gracias por resaltar el problema, lo encontré muchas veces cuando hice el tenedor pixijs ts para mis proyectos de trabajo.

Sí, Text es dolor. Sí, tenemos que pensarlo más.

Estoy de acuerdo en que setBar no es la solución más bonita. Para ser honesto, me sorprendió bastante que TypeScript no tenga soporte para este tipo de configuradores con coerción de tipos. Solo una palabra de advertencia sobre lo que significa usar una escritura más flexible o incluso any para estas propiedades con respecto al control de flujo 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));

Creo que, a la larga, la opción más limpia sería ir con algo como esto:

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());

Este tipo de set no carece de precedentes, ya que es exactamente cómo se implementa PIXI.Point . Básicamente, todas las API orientadas al usuario probablemente aceptarían la instancia Bar "tal cual" sin tener que llamar a get todas partes manualmente.

Naturalmente, este sería un cambio radical, por lo que no es algo para el futuro cercano, solo quería aportar mi granito de arena.

Y acabo de darme cuenta de que mi sugerencia anterior ya no sería una propiedad "real", por lo que cosas como Object.assign ya no funcionarían con el setter. Así que tal vez no sea la mejor idea después de todo.

Hola, soy usuario de PixiJS desde hace mucho tiempo y usuario de Typescript. Podría contribuir en esto: parece que la mayoría de los paquetes se han realizado en este punto. Aparte de los de lona. ¿Hay algo en lo que pueda ayudar?

@lloydevans sí!!! ¿Te apetece hacer preparar o mapa de bits de texto? Ambos son buenos, esperemos que no sean paquetes súper complicados.

@bigtimebuddy ¡Genial! Podría echar un vistazo a hacer text-bitmap.

¡Suena bien! Haga un borrador de PR una vez que comience para que podamos rastrearlo aquí.

OK lo haré. Echaré un vistazo a algunas de las conversiones y relaciones públicas existentes ahora y haré lo mismo.

Parece que los paquetes individuales en npm todavía no tienen tipos. ¿Supongo que eso es algo que se puede abordar después de que se solucione este problema? Sería genial poder usarlos para reducir los tamaños de construcción sin sacrificar la seguridad de tipo.

¡Llega a casa a todos! ¡Solo quedan un par de paquetes!

Muchas gracias a @Zyie , @ivanpopelyshev , @SerG-Y, @eXponenta y todos los demás colaboradores que ayudaron a hacer posible esta migración.

¿Fue útil esta página
0 / 5 - 0 calificaciones