[英]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.