在 TypeScript 中,将类作为参数传递的时候,如何表示该参数的类型?

例如有一个类:

class Widget {}

我希望这个类的使用方不直接将其实例化,而是由框架统一实例化,使用方通过一个代理来访问由框架提供的实例:

// Widget 代理
class WidgetProxy<W extends Widget>{
  private widgetInstance!: W;
  // 这里的 ClassWidget 是类本身,例如直接传入 Widget,而不是类的实例 new Widget();
  constructor(ClassWidget: any/*ClassItSelf<W>*/){
    // 这里简化了实例化的步骤,实际使用中这个实例化过程是在框架里面完成
    // @ts-ignore
    this.widgetInstance = new ClassWidget() as W;
  }

  public getWidgetInstance():W{
    return this.widgetInstance;
  }
}

// 使用方
class UserInterface {
  private widgetProxy = new WidgetProxy<Widget>(Widget);

  public testIfWidgetReady(){
    return this.widgetProxy.getWidgetInstance();
  }
}

参照 TS 提供的 lib.es5.d.tsConstructorParameter的实现,我实现了如下 ClassItSelf

type ClassItSelf<T> = new (...args: any[]) => T;

ClassItSelf<W>作为WidgetProxy构造函数的参数类型,可以做到不报错,但是会丢失Widget的构造函数的参数类型和 Widget 的静态属性。

阅读 3.8k
2 个回答
class WidgetA extends Widget {
    constructor(a: number, b: ClassA /* , c ... */){
        super();
    }
}

既然使用者可以扩展Widget,那你实例化对象就无法“手动完成”,即使你知道构造函数参数列表。这种情况应该引入 di 来解决,让使用者去“配置”关联关系,框架层面通过关系再做组合,最终构造扩展后的Widget

一个玩具供参考 https://github.com/unicreator...

都做到这一步了,只需要明确 new () 里面的参数列表就好了啊

class Test {
  constructor(s: String) { }
}

function create(c: new(s: string) => Test): Test {
  return new c("hello");
}

class Widget { }

type ClassItSelf<T> = new () => T;
const WidgetClass: ClassItSelf<Widget> = Widget;

const instance = new WidgetClass();

传送门:TypeScript Playground


再补充(2023-02-16)

那么你想要的是这个?

class Widget {
  public static widgetDescription = "这是一个组件"
  public test() {}
}

type ClassItSelf<T> = (new () => T) & (typeof Widget);

const x: ClassItSelf<Widget> = Widget;
x.widgetDescription;

const y = new x();
y.test();
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏