在打字稿中实例化动态加载的class?

Instantiate a dynamic loaded class in typescript?

我有一个摘要 class 设置如下:

export abstract class RuleValidator {
  public validate(condition: any, data: any) : boolean {
    return false;
  }
}

我编写了一个扩展 class 如下:

import { RuleValidator } from "./interfaces/ruleValidator";

export class WeightValidator extends RuleValidator {
  constructor() {
    super();
  }
  validate(condition: any, data: any) : boolean {
    console.log(JSON.stringify(condition));
    return true;
   }
   public test() {
     console.log('Test successful');
   }
}

我试图仅在验证规则时加载 class(权重验证器)。 IE 我的规则集类似于 { "weight": { "gte": 2, "lt":9} }

在我的“引擎”中有以下代码:

export class RulesEngineService() {
  validators = {};
  private validate(rule: Rule, data: any){
    for (const requirement of rule.requirements) {
      for (const condition in requirement){
        let validator = this.getRuleValidator(condition);
        let result = validator.validate( requirement[condition], data)
      }
    }

  }

  private  getRuleValidator(validatorName: string): RuleValidator {
    validatorName = validatorName ? validatorName.toLocaleLowerCase() : validatorName;

    // populate only if validator doesn't exist
    if (typeof this.validators[ validatorName ] === 'undefined') {
      const Validator = require( '../ruleValidator/' + validatorName);
      const validator = new Validator();
      this.validators[validatorName] = validator;
      return null;
    }
    else {
      return this.validators[validatorName]
    }
  }
}

过去,在 JavaScript Node 中,我可以简单地对包含 class 的文件执行 require 并使用 var Validator = require('/path/to/lib' + filename); validator = new Validator() 实例化它,如您在在上面调用。

我的问题是,当它尝试 运行 validator = new Validator(); 代码行时,我得到一个错误 Validator is not a function。我在 VSCode 调试器中看到对象结构看起来像

   {
     WeightValidator: class WeightValidator.....
     __esModule:true
   }

我需要的是存储对 class 我只是“需要”的实例的引用,并将其存储在我设置的对象中以及 return 的引用调用方法。这样,我就可以调用 class 中的验证函数。我计划创建许多不同的验证器,它们将包含自定义逻辑来完成验证工作。

我尝试了一些不同的想法,比如用这样的方式将负载包​​装在一个承诺中:

      const validator  = (async () => {
        let f = '../ruleValidator/' + validatorName;
        const v = await import(f);
        return v; 
      })().then(v => {
        const s = v.validate(condition, data)
        return s;
      });

我被告知验证方法不存在。另外,老实说,我还不需要 运行 async。我只想在 TypeScript 中复制 JavaScript 要求的功能。

您可以将 class 导出标记为 default 导出,这在 Typescript documentation:

中有说明
// 'weightValidator.ts'
import { RuleValidator } from "./interfaces/ruleValidator";


// use the `default` export
export default class WeightValidator extends RuleValidator {
  
  //...

}

有了它你应该可以使用

// 'ruleEngineService.ts'
const Validator = require( '../ruleValidator/' + validatorName);
const validator = new Validator();

另一种方法可能是:

// 'weightValidator.ts'
import { RuleValidator } from "./interfaces/ruleValidator";

export class WeightValidator extends RuleValidator {
  
  //...

}

// use a separate export which has the same name for all validators.
export const sameExportNameForAllValidators = WeightValidator;

然后:

// 'ruleEngineService.ts'
const Validator = require( '../ruleValidator/' + validatorName).sameExportNameForAllValidators;
const validator = new Validator();