如何初始化存储在抽象变量class中的class?

How to initialize a class stored in a variable of an abstract class?

我正在开发一个 TypeScript 项目是为了好玩 运行 遇到一个有趣的情况,我无法实例化对 class 的引用,可能是因为 TypeScript 假定它是一个 实例 class.

const programClass: Program = this.fetchProgram(programName) as Program

fetchProgram 是从 map returning program class,其中每个程序都是动态加载的文件。

地图创建示例:

const programPath = "../../../programs"
const programFiles = fs.readdirSync(path.join(__dirname, programPath))

programFiles.forEach(file => {
  file = path.join(__dirname, programPath, file)
  const cmdClass = require(file).default
  const command = new cmdClass() as Program
  this.commands.set(command.alias, command)
})

每个 “程序” 是一个导出 class 的文件,它扩展了摘要 class program.

示例程序:

export default class ProgramEcho extends Program {
  alias = "echo"
  constructor(options: ProgramOptions) {
    super(options)
    console.log(`DEBUG: Program Instantiated: Echo`)
  }
}

现在, 回到第一个代码片段。这确实被视为 Program 的一个实例,而我确实需要它是某种类型的可构造 class,它扩展了 Program.

const programClass: Program = this.fetchProgram(programName) as Program
const program = new programClass()

错误:

const programClass: Program
This expression is not constructable.
  Type 'Program' has no construct signatures.ts(2351)

看起来你可以做一个简单的工厂模式,其中抽象 class program 有一个名为 create 的函数,它 return 是一个新的 Program , 但你不能 return 一个抽象的实例 class.

如您所见,类型 Program 指的是 Program class 的一个实例。你想要的是一个可以创建 Program 实例的构造函数。假设你所有的 Program subclasses 都采用相同的构造函数参数,你想要的类型是:

type ProgramConstructor = new (options: ProgramOptions) => Program;

这允许您创建一个实例:

const programClass: ProgramConstructor = this.fetchProgram(programName) as ProgramConstructor;
const options: ProgramOptions = ??? // not sure where this comes from
const program = new programClass(options);

Typescript Playground Link