打字稿 - 继承静态属性没有静态关键字
Typescript - inheriting static properties without static keyword
我有多个 class 代表数据库中的实体。
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
}
每个 class 扩展实体或其子项之一。
在初始化阶段,我将 classes 放入数组 [Entity_A, Entity_B, ...]
中,遍历它们并读取它们的属性以了解如何设置应用程序。静态属性基本上是我的配置。
问题是,typescript 中没有静态契约,这使得它很容易出错,而且很难找到它(而且我读过这通常不是一个好的做法)。
我可以将静态属性更改为方法并简单地执行 new currentClass().property
。
但我相信一定有更好的方法。
有什么想法吗?
编辑(我真正想要的):
我希望能够在 classes 中安全地定义 "configuration"(类型检查 + 强制覆盖)并在给定 类
数组时轻松访问它
您可以在模块中隐藏实际的 Entity
class(不导出它),并且只导出一个函数,该函数将所需的静态字段作为参数。此函数将 return 从隐藏基数 class 派生的 class 并将覆盖静态字段。此函数的结果将用作派生实体的基础 class:
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());
这种方法使字段保持静态,并强制实施者指定它们。据我所知,诸如强制您实现抽象方法等功能也很有效。
如果你需要一个派生实体的 class 但它是其他 class 的基础 class 你可以应用相同的模式,即将它封装在一个函数中并使用作为基础的函数 class.
我有多个 class 代表数据库中的实体。
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
}
每个 class 扩展实体或其子项之一。
在初始化阶段,我将 classes 放入数组 [Entity_A, Entity_B, ...]
中,遍历它们并读取它们的属性以了解如何设置应用程序。静态属性基本上是我的配置。
问题是,typescript 中没有静态契约,这使得它很容易出错,而且很难找到它(而且我读过这通常不是一个好的做法)。
我可以将静态属性更改为方法并简单地执行 new currentClass().property
。
但我相信一定有更好的方法。
有什么想法吗?
编辑(我真正想要的): 我希望能够在 classes 中安全地定义 "configuration"(类型检查 + 强制覆盖)并在给定 类
数组时轻松访问它您可以在模块中隐藏实际的 Entity
class(不导出它),并且只导出一个函数,该函数将所需的静态字段作为参数。此函数将 return 从隐藏基数 class 派生的 class 并将覆盖静态字段。此函数的结果将用作派生实体的基础 class:
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());
这种方法使字段保持静态,并强制实施者指定它们。据我所知,诸如强制您实现抽象方法等功能也很有效。
如果你需要一个派生实体的 class 但它是其他 class 的基础 class 你可以应用相同的模式,即将它封装在一个函数中并使用作为基础的函数 class.