我有一个应用程序使用一些带有 Mixin 模式的泛型类,并且正在尝试实现一个属性 getter,该属性对于 90% 的 mixin 用户来说是相同的,但并非全部......
我惊讶地发现:
当我尝试覆盖子类的mixin中定义的属性getter时,发现了一个意想不到的问题。
下面是一个小代码片段,试图演示所有 3 个行为 - 谁能帮助我理解为什么第 3 点是错误以及是否有好的方法来修复它?我想保证
TextThing
被迫实现抽象属性的任何孩子的安全...
/**
* Basic interface objects should implement
*/
export interface ITextThing<T> {
dataSource: T;
html(): string;
get text(): string;
}
/**
* Abstract base class with partial implementation
*/
export abstract class TextThing<T> implements ITextThing<T> {
dataSource: T;
constructor(data: T) {
this.dataSource = data;
}
abstract html(): string;
abstract get text(): string;
}
type AbstractOrConcreteConstructor<T> = (new (...args: any[]) => T) | (abstract new (...args: any[]) => T);
/**
* A mixin with extra functionality
*/
export function WithCounter<T extends AbstractOrConcreteConstructor<{}>>(SuperClass: T) {
return class extends SuperClass {
_counter: number;
constructor(...args: any[]) {
super(...args);
this._counter = 0;
}
get count(): number {
return this._counter;
}
get text(): string {
return `[${this._counter}]`;
}
};
}
/**
* The problem class: Using the mixin...
*/
export class TextWithCounter<TData> extends WithCounter(TextThing)<TData> {
constructor(data: TData, initialCount = 0) {
super(data);
this._counter = initialCount;
}
// Overriding a getter defined in the mixin seems fine...
override get count(): number {
return this._counter + 1;
}
// Overriding a base class abstract function implemented in mixin seems fine...
html(): string {
return `<p><strong>${this.count}: </strong>${this.dataSource}</p>`;
}
// But base class abstract getter implemented in the mixin throws an error?
// > 'text' is defined as a property in class 'WithCounter<typeof TextThing>.(Anonymous class)
// & TextThing<TData>', but is overridden here in 'TextWithCounter<TData>' as an
// accessor.ts(2611)
override get text(): string {
return `[${this.count}]: ${this.dataSource}`;
}
}
该项目当前使用 TypeScript v4.5.4,但如果有帮助的话可能可以升级?我不太清楚这是一个错误/限制还是我们的代码的问题......
我认为这是由这个错误引起的。我认为 getter 通常被视为只读属性,这在像这样继承时会成为一个问题。但是,方法可以正常工作,因此此问题的解决方案可能是将
get text()
的声明和定义替换为 getText()
,然后用适当的方法调用替换 getter 用法(.text
变为 .getText()
)。