TypeScript: шаблон фабрики для использования динамического импорта не позволяет создавать новый экземпляр объекта для композиции
Я реализую фабричный шаблон в Typescript с динамическим импортом, чтобы я мог инициализировать загрузку, инициализировать (с необходимой композицией) требуемый модуль во время выполнения.
Я могу загрузить модуль динамически по требованию, как https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
Однако это не позволяет мне инициализировать загруженный модуль. Хотя в консоли разработчика я могу выполнить инициализацию и даже легко скомпоновать ее, инициализируя подмодули и классы, скомпонованные в модуле.
Изо всех сил пытался найти это решение и перепробовал много вещей, но не смог его решить. В C# мы можем сделать это, используя отражение, и создавать экземпляры библиотек и классов в виде отложенной загрузки без прямой ссылки на них.
Я получаю сообщение об ошибке: "// я не могу использовать 'new' с выражением, тип которого не содержит вызов или конструкцию signature.ts(2351)", когда я делаю
let y: Interfaces.IComponent = new comp();
построить его и назначить его varebale с типом интерфейса, который реализует этот объект.
то же самое для родительского типа класса, который расширяет компонент
let x: ComponentImpl = new comp();
Пожалуйста, посмотрите код машинописи ниже.
import { Interfaces } from 'shared';
import { ComponentImpl } from 'core';
export default class Factory {
private _loadedModules: Map<string, Interfaces.IComponent> = new Map<string, Interfaces.IComponent>();
private static _instace: Factory;
private constructor() {
}
public static get Instance(): Factory {
return this._instace || (this._instace = new this());
}
public getComponent(component: string): Promise<Interfaces.IComponent> {
return new Promise<Interfaces.IComponent>(async (resolve, reject) => {
let comp = this._loadedModules.get(component);
if (comp !== null) {
comp = await import(`./${component}`);
if (comp) {
// ----------------------------------------------------------------------------
// ** NOTE: On run time I can see the module is loaded corrctly and I can initialze its sub classes in developer console.
// like controller = new comp.controller(); (get console log from constructor)
// controller.sayHello();
// controller.setAPIInstance(new comp.getAPI());
// controller.saveToAPI();
let y: Interfaces.IComponent = new comp(); // Cannot use 'new' with an expression whose type lacks a call or construct signature.ts(2351)
let x: ComponentImpl = new comp(); // Cannot use 'new' with an expression whose type lacks a call or construct signature.ts(2351)
this._loadedModules.set(component, comp);
resolve(comp);
} else {
reject("Unable lo load module");
}
} else {
setTimeout(() => {
resolve(comp);
}, 1);
}
});
}
}
0 ответов
Вы можете попробовать следующее решение, которое сработало в моем случае:
let x: ComponentImpl = new (comp as typeof ComponentImpl )()
См. Также этот билет из TypeScript: https://github.com/Microsoft/TypeScript/issues/2081