Typescript - 继承静态属性而不使用static关键字

时间:2018-02-01 20:18:00

标签: angular typescript oop static-methods

我有多个代表数据库实体的类。

abstract class Entity {
    static columns: Column[];
    static showInNav: boolean;
    static dependencies: string[];
    // non-static fields
}
class Entity_A extends Entity {
    //static properties redeclaration
    //non-static properties
}
class Entity_B extends Entity {
    //static properties redeclaration
    //non-static properties
}

每个班级都会扩展实体或其中一个孩子。 在初始化阶段,我将类放在数组[Entity_A, Entity_B, ...]中,迭代它们并读取它们的属性以了解设置应用程序的热点。静态属性基本上就是我的配置。

问题是,打字稿中没有静态合约,容易犯错误,很难找到它(而且我已经读过它并不是一般的好习惯)。 我可以将静态属性更改为方法,只需执行new currentClass().property。 但我确信必须有更好的方法。

有什么想法吗?

编辑(我真正想要的): 我希望能够安全地定义"配置"在类(类型检查+强制重写)中,并在给定类的数组时轻松访问它

1 个答案:

答案 0 :(得分:1)

您可以隐藏模块中的实际Entity类(不导出它),只导出一个函数,该函数将所需的静态字段作为参数。此函数将返回从隐藏基类派生的类,并将覆盖静态字段。此函数的结果将用作派生实体的基类:

<强> entity.ts

abstract class EntityImpl {
    static columns: Column[];
    static showInNav: boolean;
    static dependencies: string[];
    abstract doStuff(): void;
}
export interface Column {
    // Dummy for this sample
}

export function Entity(required: { columns: Column[]; showInNav: boolean; dependencies: string[];}) {
    abstract class Entity  extends EntityImpl {
        static columns: Column[] = required.columns
        static showInNav: boolean = required.showInNav;
        static dependencies: string[] = required.dependencies;
    }
    return Entity;
}
// Export a type definition so we can use the base type as needed 
export type Entity = EntityImpl;
// Export a type definition that represents the type, so we can access all the static props 
export type EntityClass = typeof EntityImpl;

<强> impl.ts

import { Entity, EntityClass } from './entity'

class Entity_A extends Entity({
    columns: [],
    dependencies: [],
    showInNav: true
}) {
    doStuff(): void {} //abstract methids HAVE to be imlementes as expected
}

class Entity_B extends Entity({
    columns: [],
    dependencies: [],
    showInNav: false
}) {
    doStuff(): void {}
}

// Array of types, with save access
var allClasses : Array<EntityClass> = [Entity_A, Entity_B];
for(let type of allClasses) {
    console.log(type.showInNav);
}

// Array of instances, with save access
var data: Array<Entity> = [new Entity_A(), new Entity_B()];
data.forEach(x => x.doStuff());

这种方法使字段保持静态,并强制实现者指定它们。另外,据我所知,强制你实现抽象方法的功能。

如果您需要一个派生实体但是其他类的基类的类,则可以应用相同的模式,即将其封装在函数中并将该函数用作基类。