TypeScript: шаблон фабрики для использования динамического импорта не позволяет создавать новый экземпляр объекта для композиции - PullRequest
0 голосов
/ 25 февраля 2019

Я реализую фабричный шаблон в 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);
                }

            });
        }
    }

1 Ответ

0 голосов
/ 14 марта 2019

Вы можете попробовать следующее решение, которое сработало в моем случае:

let x: ComponentImpl =  new (comp as typeof ComponentImpl )()

См. Также этот билет из TypeScript: https://github.com/Microsoft/TypeScript/issues/2081

...