在 TypeScript Mixin 之后重写抽象 getter

问题描述 投票:0回答:1

我有一个应用程序使用一些带有 Mixin 模式的泛型类,并且正在尝试实现一个属性 getter,该属性对于 90% 的 mixin 用户来说是相同的,但并非全部......

我惊讶地发现:

  1. 定义抽象方法,在 mixin 中实现它们,并在子类中重写它们
  2. 可以在 mixin 中定义新的属性 getter 并在子类中重写它们
  3. 但是,尝试定义抽象属性 getter,在 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,但如果有帮助的话可能可以升级?我不太清楚这是一个错误/限制还是我们的代码的问题......

typescript typescript-generics typescript-mixins
1个回答
0
投票

我认为这是由这个错误引起的。我认为 getter 通常被视为只读属性,这在像这样继承时会成为一个问题。但是,方法可以正常工作,因此此问题的解决方案可能是将

get text()
的声明和定义替换为
getText()
,然后用适当的方法调用替换 getter 用法(
.text
变为
.getText()
)。

© www.soinside.com 2019 - 2024. All rights reserved.