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:
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
CodePudding user response:
The imported constructor should be extracted from 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.
Not related small suggestions:
- rename
getInstance
->getConstructor
- change return type to
Promise<IAdapterConstructor>
where IAdapterConstructor
is:
interface IAdapterConstructor {
new(someProperty: string): IAdapter;
}