машинописный тип класса, который должен быть инициализирован - PullRequest
0 голосов
/ 29 апреля 2019
let circle: Circle;

В этой строке указано, что circle является экземпляром Circle.Есть случай, когда у меня есть список фабрик, они не были инициализированы (список классов).Я должен обработать их статические свойства.Какой тип я должен использовать для этого?

Я получаю такую ​​ошибку:

 error TS2576: Property 'version' is a static member of type 'MigrationContainerBase'

Вот код, где я получаю ошибку:

@injectable()
export class MigrationManagerContainer implements IMigrationManagerContainer {

    @inject(ContainerType.CurrentVersion)
    private currentVersionContainer: ICurrentVersionContainer;

    @multiInject(ContainerType.Migration)
    private migrations: MigrationContainerBase[];

    public getMigrations() {
        return Promise.resolve(this.migrations.sort((a, b) => {
            compareVersions(a['version'], b['version'])
        }));
    }
    ....
 }

@migration('0.0.2')
class _0_0_2_Migration extends MigrationContainerBase {
    up() {
        project.state = 'State->0.0.2'
    }

    down() {
        project.state = 'State->0.0.1'
    }
}

@migration('0.0.3')
class _0_0_3_Migration extends MigrationContainerBase {
    up() {
        project.state = 'State->0.0.3'
    }

    down() {
        project.state = 'State->0.0.2'
    }
}

@migration('0.0.1')
class _0_0_1_Migration extends MigrationContainerBase {
    up() {
        project.state = 'State->0.0.1'
    }

    down() {
        project.state = 'State->0.0.0'
    }
}

1 Ответ

2 голосов
/ 30 апреля 2019

Я не уверен, как именно это реализовать с помощью декораторов @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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...