typescript中抽象类中的静态工厂

typescript中抽象类中的静态工厂,typescript,Typescript,考虑以下几点: export type=Record 可处理的导出类型={ 过程(args?:jsa):承诺 } 抽象类AbstractTaskProcessor实现可处理{ 抽象过程(args?:T):承诺 } 这是我工作制度的一部分。但有时为了测试,我想马上测试process方法,所以我想添加一个静态助手方法,如下所示 抽象类AbstractTaskProcessor实现可处理{ 抽象过程(args?:T):承诺 静态runNow(args?:T):承诺{ const instance=n

考虑以下几点:

export type=Record
可处理的导出类型={
过程(args?:jsa):承诺
}
抽象类AbstractTaskProcessor实现可处理{
抽象过程(args?:T):承诺
}
这是我工作制度的一部分。但有时为了测试,我想马上测试process方法,所以我想添加一个静态助手方法,如下所示

抽象类AbstractTaskProcessor实现可处理{
抽象过程(args?:T):承诺
静态runNow(args?:T):承诺{
const instance=newthis()
返回instance.process(args)
}
}
但是我得到了一个
TS2511:无法创建抽象类的实例。

我希望DSL是像

MyTaskProcessor.runNow({accountId:123123,accountName:'Lorum'})
有人对此有好的模式吗



我在TS 4.2上

从Typescript 4.2开始,现在支持抽象构造函数签名。见:

如果由于某种原因无法升级,则旧解决方案需要常规构造函数签名和类型断言:

type JSONable = Record<string, string | number>

type Processable = {
  process(args?: JSONable): Promise<void>
}

type ProcessableConstructor = { new (): Processable }  // Constructor signature

abstract class AbstractTaskProcessor<T extends JSONable> implements Processable {

  abstract process(args?: T): Promise<void>

  static runNow<T extends JSONable> (args?: T): Promise<void> {
    const instance = new (this as any as ProcessableConstructor)()   // Type assertion
    return instance.process(args)
  }
}

class MyTaskProcessor extends AbstractTaskProcessor<JSONable> {
  async process (args: JSONable) { return }
}

MyTaskProcessor.runNow({accountId: 123123, accountName: 'Lorum' })
typejsonable=Record
可处理的类型={
过程(args?:jsa):承诺
}
类型ProcessableConstructor={new():Processable}//构造函数签名
抽象类AbstractTaskProcessor实现可处理{
抽象过程(args?:T):承诺
静态runNow(args?:T):承诺{
const instance=new(这是任何可处理构造函数)(//类型断言
返回instance.process(args)
}
}
类MyTaskProcessor扩展了AbstractTaskProcessor{
异步进程(args:JSONable){return}
}
MyTaskProcessor.runNow({accountId:123123,accountName:'Lorum'})

如果您只需键入@ccarton显示的内容,您的示例就可以发挥作用。但是,如果它仅用于测试,并且您希望保留
T extends JSONable
的类型信息,我建议为它编写一个函数,如:

MyTaskProcessor类扩展了AbstractTaskProcessor{ 进程(args?:{test:number,test2:string}):承诺{ 返回承诺。解决(); } } 可处理的类型={ 过程(args?:T):承诺 } 导出函数runNow(processorClass:new()=>Processable,args:T){ const instance=新的processorClass(); 返回instance.process(args) } runNow(MyTaskProcessor,{test:5,test2:“hello”}) runNow(MyTaskProcessor,{test:5,test2:3})//类型'number'不能分配给类型'string' MyTaskProcessor.runNow({test:5,test2:3})//没有类型安全性,没有警告
更新了@Linda Paiste的精练版本

您不应该只测试具体的类行为吗?我的意思是,实例化一个抽象类不是一开始就违背了拥有一个抽象类的目的吗?如果这是现在唯一可以测试
进程
方法的方法,那么这次你可能会想让编译器闭嘴(不过,很好奇其他人怎么想)。你能举个例子说明他不必用abstract关键字打字吗?我看不出这将如何改变类型转换的需要。这是一个很好的版本,因为它不需要实例化抽象类,也不只是为了测试目的在类上定义方法。我已经用一个简短的推断描述和到文档的链接更新了答案。这不是必需的。我最初想给出一个完整的答案,其中也包括卡顿在回答中描述的部分。但他的答案是第一位的,这只是我使用的静态runNow示例的一个残余(你可以在操场上看到我的完整代码)。如果有人调用AbstractTaskProcessor.runNow,它应该充当运行时保护,因为由于“as any”-强制转换,没有编译时保护。我将更新答案并将其删除。@Micro S。我将调整
定义,以确保构造函数不需要任何参数(或要求将构造函数参数传递给
runNow
)。但这是一个非常好的答案。很高兴看到新的回答者真的很有知识:)修改版本,没有
推断和通用的
可处理的