在打字稿中实例化动态加载的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();
我有一个摘要 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();