繁体   English   中英

在 TypeScript class 上添加抽象/可继承 static 构造函数辅助方法

[英]Adding abstract/inheritable static constructor helper method on TypeScript class

我有一个抽象的 API class 和一些基本的 api 逻辑,用于我们的应用程序,我在其他各种类中扩展:

interface Options {
  authToken?: string;
  ip?: string;
  endpointPrefix?: string;
}

abstract class AbstractApi {
  private authToken?: string;
  private ip?: string;
  private endpointPrefix?: string;

  constructor({
    ip = undefined,
    authToken = undefined,
    endpointPrefix = '',
  }: Options) {
    this.authToken = authToken;
    this.ip = ip;
    this.endpointPrefix = endpointPrefix;
  }

  protected async get() {
    // ...
  }

  protected async post() {
    // ...
  }
}
class TodosApi extends BaseApi {
  constructor() {
    super({ endpointPrefix: '/todos' });
  }

  getTodos(/* ... */) {
    this.post(/* ... */);
  }
}

我想确保 AbstractApi 的每个实例都有一个 static 便利构造函数: .new() 例如const todos = await TodosApi.new().getTodos()

我如何确保每个孩子都自动使用此方法?


我尝试过但没有奏效的一些事情:

static create(data) {
  return new this.constructor(data);
}
static create(data) {
  return new this(data)
}

很难确切地知道“没有工作”是什么意思。 你的意思是你有一个编译器错误? 或者它在运行时不起作用? 或两者? 无论如何,我将尝试继续并希望解决您面临的问题:

由于 static 方法的this上下文将是 class 构造函数而不是 class 实例,因此您将需要使用new this()而不是new this.constructor() 假设具体子类将具有不同的构造函数参数列表要求,您的 static create()方法可能应该采用rest 参数 所以在运行时你希望它看起来像这样:

static create(...args) {
    return new this(...args);
}

现在我们只需要为该方法提出适当的类型来满足编译器并在您尝试使用它时产生合理的行为。 对于实例方法,显而易见的解决方案涉及所谓的多态this ,其中this类型表示“无论当前的 class 实例类型是什么”,即使对于子类也是如此。 不幸的是,(从 TS3.7 开始)对于 static 方法没有类似的多态this 相反,我们需要使用涉及 generics 和this参数解决方法

static create<A extends any[], R>(this: new (...args: A) => R, ...args: A) {
    return new this(...args);
}

这意味着create将作为某个具体构造函数类型的方法调用,该构造函数类型接受一些参数列表A并生成一些实例类型R (您可以约束R来扩展AbstractApi但这里不需要)。 让我们看看它是否有效:

TodosApi.create().getTodos(); // okay
TodosApi.create("bad argument"); // error: expected 0 arguments, got 1
AbstractApi.create({}); // error: this context of create does not match

所以你想要的使用效果很好。 您可以看到TodosApi.create()需要与TodosApi构造函数相同的参数列表(即没有参数),因此如果您将错误的内容传递给它,则会收到错误消息。 如果您尝试直接在AbstractApi上调用create() ,编译器会给您一个错误,因为create()要求其this上下文是可构造的,而AbstractApi是抽象的,因此不可构造。

那对你有用吗? 希望有帮助; 祝你好运!

链接到代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM