我有多个代表数据库实体的类。
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
。
但我确信必须有更好的方法。
有什么想法吗?
编辑(我真正想要的): 我希望能够安全地定义"配置"在类(类型检查+强制重写)中,并在给定类的数组时轻松访问它
答案 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());
这种方法使字段保持静态,并强制实现者指定它们。另外,据我所知,强制你实现抽象方法的功能。
如果您需要一个派生实体但是其他类的基类的类,则可以应用相同的模式,即将其封装在函数中并将该函数用作基类。