打字稿必须初始化的类的类型

时间:2019-04-29 19:16:26

标签: typescript oop

let circle: Circle;

此行表示circleCircle的实例。在某些情况下,我有一个工厂列表,但它们尚未初始化(类列表)。我必须处理它们的静态属性。我应该使用哪种类型?

我收到这样的错误:

 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 个答案:

答案 0 :(得分:2)

由于您尚未提供@migration@multiInject装饰器,因此我不确定该如何实现。但是,由于您是专门询问在这种情况下如何键入的,因此我希望这将为您提供足够的信息,以便您提出自己的实现。

您是正确的。当您声明类似

const circle: Circle;

您是说名为circle的变量包含类型为Circle实例。这里的重要区别是:的左侧是“ 值空间”,而右侧是“ 类型空间” < sup> 1 。在TypeScript中,类以某种方式占用类型空间和值空间,因为它们的构造函数是值。如果要引用值空间名称Circle表示的类型,则可以使用typeof关键字(这与JavaScript中的typeof operator不同)。

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编译器内部的情况。