Я не уверен, как именно это реализовать с помощью декораторов @migration
и @multiInject
, поскольку вы их не предоставили. Но так как вы конкретно спрашиваете о том, как печатать в таком сценарии, я надеюсь, что это позволит пролить достаточно света на него, чтобы вы могли придумать собственную реализацию.
Ты прав. Когда вы объявляете что-то вроде
const circle: Circle;
Вы говорите, что переменная с именем circle
содержит экземпляр типа Circle
. Важным отличием здесь является то, что левая часть :
относится к " пространству значений ", а правая часть относится к " пробелу типа " 1 . В TypeScript классы некоторым образом занимают пространство типов и пространство значений, потому что их функции конструктора являются значениями. Если вы хотите сослаться на тип, который представляет имя пространства значений Circle
, вы можете использовать ключевое слово typeof
(это отличается от оператора typeof
из JavaScript).
const circleClass: typeof Circle = Circle;
const circle = new circleClass(); // inferred type: Circle
В качестве альтернативы вы можете описать статические свойства класса или его конструктора класса, например:
const circleClass: { new(): Circle } = Circle;
const circle = new circleClass(); // inferred type: Circle
Само по себе это может не помочь в вашем случае. С абстрактным классом вы обычно подразумеваете, что каждый подкласс должен предоставлять своих собственных членов, которые удовлетворяют некоторому ограничению, но это не может быть сделано со статическими членами. Чтобы обойти это, вам, вероятно, лучше создать отдельный интерфейс для статического описания, например:
interface IMigrationContainer {
new(): MigrationContainerBase
version: string;
// ... any other static members declared here
}
abstract class MigrationContainerBase {
abstract up(): void;
abstract down(): void;
// any other abstract instance members here
}
И используйте интерфейс в своем классе контейнера миграции:
private migrations: IMigrationContainer[];
public getMigrations() {
return Promise.resolve(this.migrations.sort((a, b) => {
return compareVersions(a['version'], b['version']);
}));
}
Тогда ваши классы миграции должны выглядеть примерно так (обратите внимание, что я не использую implements IMigrationContainer
):
class _0_0_1_Migration extends MigrationContainerBase {
static version: string = "0.0.1";
up() {}
down() {}
}
1. « пробел » и « пробел » не являются частью официальной терминологии. Это то, что я называю этими понятиями, потому что это помогает мне лучше понять, что происходит внутри компилятора TypeScript.