Pixi.js: Требуется помощь: обновление преобразования TypeScript

Созданный на 1 февр. 2020  ·  24Комментарии  ·  Источник: pixijs/pixi.js

Привет сообщество PixiJS,

Мы достигли важной вехи в преобразовании PixiJS в TypeScript путем преобразования ядра и всех его зависимостей. Теперь, когда мы преодолели этот горб, мы можем начать с остальных пакетов, которые зависят от этого небольшого набора базовых пакетов.

Мы определенно могли бы использовать руку разработчиков для преобразования остальных этих пакетов. Если вы заинтересованы в преобразовании пакета, пожалуйста, дайте мне знать, какой именно. Есть несколько рекомендаций по преобразованию пакетов, которые вы можете увидеть из существующих заполненных PR.

Преобразование Gotchyas

  • Мы пытаемся поддерживать JSDocs до тех пор, пока все не будет завершено, а затем конвертируем в Typedoc и после этого выдаем типы. Мы просим вас поддерживать JSDocs и убедиться, что они по-прежнему правильно создаются и отображаются через npm run docs
  • Пожалуйста, используйте git mv , чтобы переименовать файлы JS в TS, иначе мы потеряем историю Git. Некоторые графические интерфейсы Git могут не учитывать эти изменения.
  • Пожалуйста, не добавляйте модификаторы доступа public к внутренним методам или членам, оставьте доступ неопределенным в этих случаях.

Пакеты

Чтобы запросить пакет, создайте для него черновик PR.

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

Пакеты

  • [ ] pixi.js-legacy #6673 Выполняется @bigtimebuddy
  • [ ] pixi.js #6673 Выполняется @bigtimebuddy

Самый полезный комментарий

Я ненавижу вносить изменения в API, чтобы приспособиться к ограничениям набора текста, просто мне это кажется неправильным. Лично я предпочел бы использовать любой, а затем создать новый метод. Наличие такой большой поверхности API уже является бременем.

Все 24 Комментарий

Больше советов:

  • Попробуйте поместить все дополнительные import (фактически его тип импорта) отдельно от существующих импортов. Мы добавим import type , когда выйдет новая версия TS. Однако линтер не позволит вам использовать две строки import из одного модуля, в этом случае их можно смешивать.

  • Вы можете использовать нотации как Array<X> , так и X[] , я обычно использую Array<X> для структур, которые часто выталкиваются (так называемые списки). X[] для объектов с фиксированной небольшой длиной или если размер определяется в том же месте, где они создаются (обычный массив).

  • Если поле readonly изменено только в destroy() - там можно использовать преобразование any . Если он используется где-то еще - удалите readonly . Мы можем решить, сделать ли это private field + readonly property позже.

Я мог бы сделать @pixi-text эти выходные, если кто-то не опередит меня.

примечание: @pixi-tiling будет иметь PIXI.TilingSprite.from , что ночью невозможно сделать в TS. Мы можем просто осудить это.

Дерзайте, @qtiki. Я буду в сети в выходные, если вы обнаружите странные вещи.

Хорошо, @qtiki , ваш выбор будет зарезервирован после отправки проекта PR.
Спасибо!

Согласованный. Проект PR — лучший способ получить пакет для конвертации. Спасибо за помощь

Хорошо, @qtiki , ваш выбор будет зарезервирован после отправки проекта PR.
Спасибо!

Я открыл черновик PR #6390. Я просто переименовал файлы .js в .ts, чтобы внести некоторые изменения, чтобы можно было создать PR. Я постараюсь сделать фактическое преобразование в эти выходные.

Некоторые общие вещи, с которыми я столкнулся при преобразовании пакета Text в TypeScript:

Итак, я столкнулся с фундаментальной проблемой со свойствами TypeScript. Кажется, что TypeScript не поддерживает разные типы для получения и установки свойств: https://github.com/microsoft/TypeScript/issues/2521 .

В классах Text и TextStyle есть места, где это было бы огромным преимуществом. Например, fillStyle и stroke в TextStyle принимают число, которое затем преобразуется в строку, поэтому геттер не должен возвращать тип объединения с числом. Теперь, когда он возвращает тип объединения с числом, я должен преобразовать его, чтобы иметь возможность передать его в CanvasRenderingContext2D fillStyle .

Кроме того, сам класс Text принимает объект с текстовым стилем, который затем передается в new TextStyle — или экземпляр TextStyle напрямую. Точно так же здесь геттер всегда будет возвращать экземпляр TextStyle, но должен быть напечатан с тем же типом объединения, что и установщик. Таким образом, это приведет к ненужной проверке типов (или приведениям типов) в пространстве пользователя, чтобы иметь возможность вызывать методы TextStyle.

Я действительно не знаю, что было бы лучшим решением для этого в долгосрочной перспективе, но сейчас я думаю, что это просто необходимо.

Еще одна вещь, которую я заметил, заключается в том, что существует довольно много кода, в котором повторно используются локальные переменные с другим типом, что не очень хорошо работает с TypeScript. Я не хотел слишком трогать существующий код, поэтому я просто использовал типы объединения и некоторые уродливые приведения здесь и там, чтобы заставить его скомпилироваться. Я предполагаю, что такие вещи могут быть улучшены с течением времени с принципом бойскаута .

@qtiki
Почему вы пишете проблемы в этой теме вместо вашего пиара?

@qtiki
Почему вы пишете проблемы в этой теме вместо вашего пиара?

Я считаю, что это общие проблемы, с которыми люди столкнутся в другом месте при преобразовании TypeScript, а не только проблемы, связанные с текстовым пакетом. Проблема свойств для одного из них является фундаментальным вопросом проектирования на будущее, если они должны быть правильно типизированы.

Я изучал проблему с сеттерами и геттерами TypeScript, которые не могли использовать разные типы с тех пор, как столкнулся с этим. Кажется, что проблема очень сложная и может никогда не быть "исправлена". Итак, вот мое предложение для общего руководства по преобразованию этих типов свойств в TypeScript:

Это упрощенный пример того, что нам нужно: свойство, которое принимает string | number , но сохраняется внутри (и возвращается) как string . Естественно, мы могли бы вернуть свойство как string | number , но это означало бы, что пользователи API столкнулись бы с совершенно ненужными проверками типов.

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

Вот как мы можем обойти это:

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

Таким образом, пользователь получает правильный тип при чтении свойства. Пользователи TypeScript, которые хотят присвоить number bar , должны будут вызвать функцию преобразования setBar . Однако это не будет критическим изменением для существующих пользователей JavaScript, поскольку установщик свойства вызывает функцию преобразования, что означает, что установщик нетипизированного свойства действительно принимает числа.

Как вы думаете, ребята, есть ли в этом смысл? Я не уверен, как часто используется этот тип шаблона, но, по крайней мере, в текстовом пакете я сталкивался с ним более одного раза.

Я ненавижу вносить изменения в API, чтобы приспособиться к ограничениям набора текста, просто мне это кажется неправильным. Лично я предпочел бы использовать любой, а затем создать новый метод. Наличие такой большой поверхности API уже является бременем.

Я никогда не буду одобрять хаки с помощью метода set*, согласен с @bigtimebuddy , что тип any более дружелюбен, чем метод set* .

В данном случае вполне приемлемо возвращать тип (string | number) для геттера.

На самом деле, иногда setBar — хорошая идея из-за проблем с наследованием set , но нужно больше символов в префиксе, например _$setBar() :) Но не в этом случае.

@qtiki спасибо, что обратили внимание на проблему, я сталкивался с ней много раз, когда делал форк pixijs ts для своих рабочих проектов.

Да, Text — это боль. Да, мы должны думать об этом больше.

Я согласен, что setBar — не самое красивое решение. Честно говоря, я был очень удивлен, что TypeScript не поддерживает такие сеттеры с приведением типов. Просто предупреждение о том, что означает использовать более свободную типизацию или даже any для этих свойств в отношении управления потоком 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));

Я думаю, что в долгосрочной перспективе самым чистым вариантом будет что-то вроде этого:

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

Этот тип set не лишен прецедентов, поскольку именно так реализован PIXI.Point . По сути, все API-интерфейсы, ориентированные на пользователя, вероятно, примут экземпляр Bar «как есть» без необходимости вручную вызывать get везде.

Естественно, это будет кардинальное изменение, так что не в ближайшем будущем, я просто хотел вставить свои пять копеек.

И я только что понял, что мое предыдущее предложение больше не будет «настоящим» свойством, поэтому такие вещи, как Object.assign , больше не будут работать с установщиком. Так что, возможно, не самая лучшая идея в конце концов.

Привет, я давний пользователь PixiJS и пользователь Typescript. Я мог бы внести свой вклад в это - похоже, что большая часть пакетов уже сделана. Кроме холстовых. Могу ли я чем-нибудь помочь?

@lloydevans да!!! Хотите сделать подготовку или текстовое растровое изображение? Оба хороши, надеюсь, не супер сложные пакеты.

@bigtimebuddy Отлично! Я мог бы взглянуть на текстовое растровое изображение.

Звучит отлично! Пожалуйста, сделайте черновик PR, как только вы начнете, чтобы мы могли отслеживать его здесь.

Нормально будет сделать. Сейчас я посмотрю на некоторые из существующих конверсий и PR и последую их примеру.

Кажется, что отдельные пакеты в npm по-прежнему не имеют типов. Я предполагаю, что это то, что может быть решено после того, как эта проблема будет решена? Было бы здорово иметь возможность использовать их для уменьшения размеров сборки без ущерба для безопасности типов.

Всем домой! Осталась пара упаковок!

Огромное спасибо @Zyie , @ivanpopelyshev , @SerG-Y, @eXponenta и всем другим участникам, которые помогли сделать этот перенос возможным.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги