如何在 TypeScript 中构建具有精确类型返回值的 mixin 工厂

问题描述

我需要在 TypeScript 中构建一个 mixin 工厂,它可以扩展任何类,只需添加一个属性来启用其实例的唯一标识。这是它需要的一般形式(尚未添加类型):

function Unique(BaseClass) {
  return class extends BaseClass {
    public readonly uniqueId = Symbol();
  };
}

如果我在 TypeScript 的手册中输入这个函数,这个函数返回值的推断类型不包含足够的信息。例如,如果做这样的事情:

const myUniqueDog = new (Unique(Dog))();

Typescript 知道 myUniqueDog 具有 uniqueId 属性,但对从 Dog 继承的属性方法一无所知。

这个函数的返回值是否可以同时保留被扩展的类和Unique接口的类型信息?我在这些方面尝试了不同的选项,但它不起作用:

// Two constructor deFinitions needed because some classes to be extended are abstract
type ConcreteConstructor<T = {}> = new(...args: any[]) => T;
type AbstractConstructor<T = {}> = abstract new(...args: any[]) => T;
type Constructor<T = {}> = ConcreteConstructor<T> | AbstractConstructor<T>;

type IUnique<T extends {}> = T & { readonly uniqueId: symbol };

function Unique<T extends {}>(BaseClass: Constructor<T>): ConcreteConstructor<IUnique<T>> {
  return class extends BaseClass implements IUnique<T> {
    public readonly uniqueId = Symbol();
  };
}

错误如下:

类型“typeof(匿名类)”不可分配给类型“ConcreteConstructor”。 类型“(匿名类)”不可分配给类型“IUnique”。 类型“(匿名类)”不可分配给类型“T”。 “(匿名类)”可分配给“T”类型的约束,但“T”可以使用约束“对象”的不同子类型进行实例化。ts(2322)

有什么方法可以实现这一目标吗?我需要它,以便其他使用此 Unique 函数的工厂具有正确的返回类型,而无需类型断言。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)