简体   繁体   English

如何使用工厂模式使用构造函数创建代码拆分打字稿模块

[英]How to create a code split typescript module with a constructor using the factory pattern

I have a number of adapters all implemented from an interface like so我有许多适配器都是从这样的接口实现的

export interface IAdapter {
   doSomething(): void;
}

and the implemented classes look very similar and basic to what you'd expect并且实现的类看起来与您期望的非常相似和基本

export default class AdapterA implements IAdapter {
   private _property: string;
   constructor(someProperty: string) {
       this._property = someProperty;
   }
}

I have a factory for the adapters and want to use it somewhat like this我有一个适配器工厂,想像这样使用它

export abstract class AdapterFactory {
    static async getInstance(name: string) Promise<IAdapter> {
        switch(name) {
            case 'a':
                return import('./adapters/adapter-a');
            case 'b':
                return import('./adapters/adapter-b');
        }
    }
}

After the code calling the factory I'd like to be able to use the returned module to instantiate a new instance of the adapter like在调用工厂的代码之后,我希望能够使用返回的模块来实例化适配器的新实例,例如

const adapterModule = await getInstance('a');
const myNewAdapter = new adapterModule('prop');
myNewAdapter.doSomething();

When I try this within the factory I get:当我在工厂内尝试时,我得到:

Type 'typeof import("/[absolute path]/adapters/AdapterA")' provides no match for the signature 'new (someProperty: string): IAdapter'

So I tried adding a definition of new (which I didn't like) like so:所以我尝试添加 new 的定义(我不喜欢),如下所示:

export interface IAdapter {
   new(someProperty: string): IAdapter;
   doSomething(): void;
}

now I get:现在我得到:

This expression is not constructable.

any help anyone can give would be greatly received任何人都可以提供的任何帮助都会受到极大的欢迎

The imported constructor should be extracted from default :导入的构造函数 应该default 提取

const { default: adapterModule } = await getInstance('a');

The reason we need default is that since webpack 4, when importing a CommonJS module, the import will no longer resolve to the value of module.exports, it will instead create an artificial namespace object for the CommonJS module.我们需要 default 的原因是,从 webpack 4 开始,当导入 CommonJS 模块时,导入将不再解析为 module.exports 的值,而是会为 CommonJS 模块创建一个人工命名空间对象。


Not related small suggestions:不相关的小建议:

  • rename getInstance -> getConstructor重命名getInstance -> getConstructor
  • change return type to Promise<IAdapterConstructor>将返回类型更改为Promise<IAdapterConstructor>

where IAdapterConstructor is:其中IAdapterConstructor是:

interface IAdapterConstructor {
  new(someProperty: string): IAdapter;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM