Pixi.js: Precisa-se de ajuda: atualização de conversão do TypeScript

Criado em 1 fev. 2020  ·  24Comentários  ·  Fonte: pixijs/pixi.js

Olá comunidade PixiJS,

Alcançamos um marco importante na conversão do PixiJS para o TypeScript, convertendo o núcleo e todas as suas dependências. Agora que superamos esse problema, podemos começar com o restante dos pacotes que dependem desse pequeno conjunto de pacotes principais.

Definitivamente, poderíamos usar uma mão dos desenvolvedores para converter o restante desses pacotes. Se você estiver interessado em converter um pacote, por favor, deixe-me saber qual. Existem algumas diretrizes para converter pacotes, que você pode ver nos PRs concluídos existentes.

Convertendo Gotchyas

  • Estamos tentando manter os JSDocs até que tudo esteja concluído, e então converter para Typedoc e emitir tipos posteriormente. Pedimos que você mantenha JSDocs e certifique-se de que eles ainda sejam construídos e apareçam corretamente via npm run docs
  • Por favor, use git mv para renomear arquivos JS para TS, ou então perderemos o histórico do Git. Algumas GUIs do Git podem não captar essas alterações.
  • Por favor, não adicione modificadores de acesso public a métodos ou membros internos, deixe o acesso indefinido nestes casos.

Pacotes

Para reivindicar um pacote, crie um rascunho de PR para ele

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

Pacotes

  • [ ] pixi.js-legacy #6673 Em andamento @bigtimebuddy
  • [ ] pixi.js #6673 Em andamento @bigtimebuddy

Comentários muito úteis

Eu odeio fazer alterações na API para acomodar limitações de digitação, simplesmente não parece certo para mim. Pessoalmente, prefiro usar qualquer do que criar um novo método. Ter uma superfície de API tão grande já é um fardo.

Todos 24 comentários

Mais dicas:

  • Tente colocar todos os import 's extras (na verdade, seu tipo de importação) separados das importações existentes. Adicionaremos import type quando a nova versão do TS for lançada. No entanto, o linter impedirá que você use duas linhas de import do mesmo módulo, não há problema em misturá-las nesse caso.

  • Você pode usar as notações Array<X> e X[] , eu costumo usar Array<X> para estruturas que são empurradas frequentemente (também conhecidas como Listas). X[] para coisas que têm tamanho pequeno fixo ou se o tamanho é decidido no mesmo local em que são construídos (array regular).

  • Se o campo readonly for alterado apenas em destroy() - você pode usar a conversão any lá. Se for usado em outro lugar - remova readonly . Podemos decidir se faremos private field + readonly property mais tarde.

Eu poderia fazer @pixi-text neste fim de semana, a menos que alguém me supere.

nota: @pixi-tiling terá PIXI.TilingSprite.from que noite não é possível fazer no TS. Podemos apenas depreciá-lo.

Vá em frente, @qtiki. Estarei online no fim de semana caso encontre coisas estranhas.

Ok, @qtiki , sua escolha será reservada após o envio do rascunho do PR.
Obrigado!

Acordado. Draft PR é a melhor maneira de reivindicar um pacote para converter. Obrigado por ajudar

Ok, @qtiki , sua escolha será reservada após o envio do rascunho do PR.
Obrigado!

Abri o rascunho PR #6390. Acabei de renomear os arquivos .js para .ts para ter algumas alterações para poder criar o PR. Vou tentar fazer a conversão real neste fim de semana.

Algumas coisas genéricas que encontrei ao converter o pacote Text para TypeScript:

Então me deparei com um problema fundamental com as propriedades do TypeScript. Parece que o TypeScript não suporta tipos diferentes para getter e setter de propriedade: https://github.com/microsoft/TypeScript/issues/2521

Existem alguns lugares nas classes Text e TextStyle onde isso seria um grande benefício. Por exemplo fillStyle e stroke em TextStyle aceitam um número que é então convertido em uma string, portanto, o getter não deve retornar um tipo de união com um número. Agora que ele retorna um tipo de união com um número, tenho que convertê-lo para poder passá-lo para CanvasRenderingContext2D fillStyle .

Além disso, a própria classe Text aceita um objeto com o estilo de texto, que é então passado para new TextStyle - ou uma instância de TextStyle diretamente. Da mesma forma, aqui o getter sempre retornará uma instância TextStyle, mas deve ser digitado com o mesmo tipo de união que o setter. Portanto, isso fará com que algumas verificações de tipo desnecessárias (ou conversões) na área do usuário sejam capazes de chamar métodos de TextStyle.

Eu realmente não sei qual seria a melhor solução para isso a longo prazo, mas por enquanto acho que isso terá que servir.

Uma outra coisa que notei é que há um pouco de código que reutiliza variáveis ​​locais com tipos diferentes, o que não funciona muito bem com o TypeScript. Eu não queria mexer muito no código existente, então usei apenas tipos de união e algumas conversões feias aqui e ali para compilar. Acho que esse tipo de coisa pode ser melhorada ao longo do tempo com o princípio dos escoteiros .

@qtiki
Por que você escreve problemas neste tópico em vez de seu PR?

@qtiki
Por que você escreve problemas neste tópico em vez de seu PR?

Acredito que esses são problemas genéricos que as pessoas encontrarão em outros lugares com a conversão do TypeScript e não apenas problemas específicos do pacote de texto. A questão da propriedade para um é algo que é uma questão de design fundamental para o futuro, se eles forem digitados corretamente.

Eu tenho estudado o problema com os setters e getters do TypeScript que não podem usar tipos diferentes desde que o encontrei. Parece que o problema é muito complexo e pode nunca ser "consertado". Então aqui está minha sugestão para uma diretriz geral na conversão desses tipos de propriedades para TypeScript:

Este é um exemplo simplificado do que queremos: uma propriedade que aceita string | number mas é armazenada internamente (e retornada) como string . Naturalmente, poderíamos retornar a propriedade como string | number mas isso significaria que os usuários da API seriam confrontados com verificações de tipo completamente desnecessárias.

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

Veja como podemos contornar isso:

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

Desta forma o usuário obtém o tipo correto ao ler a propriedade. Os usuários do TypeScript que desejam atribuir um number a bar precisarão chamar a função de conversão setBar . No entanto, isso não seria uma alteração importante para os usuários JavaScript existentes, pois o configurador de propriedades chama a função de conversão - o que significa que o configurador de propriedades sem tipo realmente aceita números.

O que vocês acham, isso faz sentido? Não tenho certeza com que frequência esse tipo de padrão é usado, mas pelo menos no pacote de texto eu o encontrei mais de uma vez.

Eu odeio fazer alterações na API para acomodar limitações de digitação, simplesmente não parece certo para mim. Pessoalmente, prefiro usar qualquer do que criar um novo método. Ter uma superfície de API tão grande já é um fardo.

Eu nunca vou aprovar hacks com o método set*, concordo com @bigtimebuddy que o tipo any é mais amigável que o método set* .

No caso atual, é bastante aceitável retornar o tipo (string | number) para getter.

Na verdade, às vezes setBar é uma boa idéia por causa de questões de herança de set , mas precisa de mais símbolos em prefx, como _$setBar() :) Não neste caso.

@qtiki obrigado por destacar o problema, eu o encontrei muitas vezes quando fiz pixijs ts fork para meus projetos de trabalho.

Sim, Text é dor. Sim, temos que pensar mais sobre isso.

Concordo que o setBar não é a solução mais bonita. Para ser honesto, fiquei bastante surpreso que o TypeScript não tenha suporte para esses tipos de setters com coerção de tipo. Apenas uma palavra de aviso sobre o que significa usar digitação mais flexível ou até any para essas propriedades em relação ao controle de fluxo do 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));

Acho que, a longo prazo, a opção mais limpa seria usar algo assim:

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 não é sem precedentes, pois é exatamente como PIXI.Point é implementado. Basicamente, todas as APIs voltadas para o usuário provavelmente aceitariam a instância Bar "como está" sem precisar chamar o get em todos os lugares manualmente.

Naturalmente, isso seria uma mudança de última hora, então não é algo para o futuro próximo, eu só queria colocar meus dois centavos.

E acabei de perceber que minha sugestão anterior não seria mais uma propriedade "real", então coisas como Object.assign não funcionariam mais com o setter. Então talvez não seja a melhor ideia, afinal.

Olá, sou um usuário de longa data do PixiJS e usuário do Typescript. Eu poderia contribuir com isso - Parece que a maioria dos pacotes foi feita neste momento. Além dos de lona. Tem algum que eu possa ajudar?

@lloydevans sim!!! Quer fazer preparação ou bitmap de texto? Ambos são bons, espero que não sejam pacotes super complicados.

@bigtimebuddy Ótimo! Eu poderia dar uma olhada em fazer bitmap de texto.

Parece bom! Faça um rascunho de PR assim que começar para que possamos rastreá-lo aqui.

Ok, vai fazer. Vou dar uma olhada em algumas das conversões e PRs existentes agora e seguirei o exemplo.

Parece que os pacotes individuais no npm ainda não possuem tipos. Eu estou supondo que é algo que pode ser resolvido depois que esse problema for feito? Seria ótimo poder usá-los para reduzir os tamanhos de compilação sem sacrificar a segurança do tipo.

Alongamento em casa a todos! Restam apenas alguns pacotes!

Muito obrigado a @Zyie , @ivanpopelyshev , @SerG-Y, @eXponenta e todos os outros colaboradores que ajudaram a tornar essa migração possível.

Esta página foi útil?
0 / 5 - 0 avaliações