Here是如何从基类非静态成员访问子类静态成员。
我想知道:它是否也可以从基础静态成员那里做到?
我尝试过以下不起作用的代码(Stackblitz):
export class EntityBase {
// Base static property initialized using a child static memeber
public static TypeName: string = (EntityBase as any).$typeName;
public static StaticBaseMethod(): string {
return (EntityBase as any).$typeName;
}
public static seeIfWorks(): any {
return {
field: EntityBase.TypeName,
method: EntityBase.StaticBaseMethod()
};
}
}
export class Entity extends EntityBase {
public static $typeName: string = "CoolChildType";
}
// Test call
this.test = EntityBase.seeIfWorks()
seeIfWorks()
方法返回的对象的两个属性都是undefined
。
问题是没有从基本静态成员直接访问子构造函数。我到目前为止唯一的方法是将它明确地传递给基本静态方法,但也许已经有针对这个问题的语言集成解决方案。
答案 0 :(得分:0)
此类层次结构有几个问题:
EntityBase
示例中使用Entity
代替this.test = EntityBase.seeIfWorks()
,子类不参与EntityBase
中的EntityBase
,无法以这种方式引用Entity
TypeName
被硬编码为EntityBase.$typeName
,如果不在子类中重新定义或使用getter,则无法引用Entity.$typeName
EntityBase
在使用它时没有$typeName
属性,这是类设计错误。应该以任何方式定义属性EntityBase
可以直接使用,但由于未定义$typeName
而不应该使用。如果是基类,它应该是abstract
。这并不妨碍它使用静态方法(如果需要,它们可以包含运行时检查),但指定其用途。应该是:
export abstract class EntityBase {
static $typeName?: string;
static get TypeName(): string {
if (this === EntityBase) throw 'Cannot be accessed';
return this.$typeName;
}
static StaticBaseMethod(): string {
if (this === EntityBase) throw 'Cannot be accessed';
return this.$typeName;
}
static seeIfWorks(): any {
if (this === EntityBase) throw 'Cannot be accessed';
return {
field: this.TypeName,
method: this.StaticBaseMethod()
};
}
}
export class Entity extends EntityBase {
static $typeName: string = "CoolChildType";
}
答案 1 :(得分:0)
我的问题的简单答案是:您实际上可以从基类静态成员引用子静态成员。这可以通过this
关键字而不是基类名来完成(感谢@estus在他的answer中展示它。)
作为一名主要来自基于类的语言背景的开发人员,我错过了在TypeScript中使用this
静态成员的选项。
因此,每当我们想要引用子类静态成员时,可以通过用this
替换基类名来修复我的问题中的示例:
export class EntityBase {
// Static initializer doesn't work for the purpose, since it's called once during first usage of base class. Use static getter instead (below).
// public static TypeName: string = (EntityBase as any).$typeName;
// Static getter
public static get TypeName(): string {
return (this as any).$typeName;
}
public static StaticBaseMethod(): string {
return (this as any).$typeName;
}
public static seeIfWorks(): any {
return {
field: this.TypeName,
method: this.StaticBaseMethod()
};
}
}
另外,在测试时,我的拼写错误是指基类而不是子类。正确的方法是:
// Test call
this.test = Entity.seeIfWorks()
请参阅更新的Stackblitz,其中我还为两个派生类添加了一个测试用例。