TS solution using generics could look like:
Let's say that we have abstract class
export abstract class PaymentProcessor {
constructor(protected amount: number) {}
abstract process(): void;
}
We could have a lot of classes which extend the abstract class:
export class BankProcessor extends PaymentProcessor {
process(): void {
console.log(`Processed by Bank ${this.amount}`);
}
}
export class CryptoProcessor extends PaymentProcessor {
process(): void {
console.log(`Processed by Crypto ${this.amount}`);
}
}
....
Let's say that we have a factory class that generates instances dynamically:
export class PaymentProcessorFactory {
static createProcessor<T extends PaymentProcessor>(
processorClass: new (amount: number) => T,
amount: number
): T {
return new processorClass(amount);
}
}
Then we can dynamically load TS class via
const bankProcessor = PaymentProcessorFactory.createProcessor(BankProcessor, 10);
const cryptoProcessor = PaymentProcessorFactory.createProcessor(CryptoProcessor, 20);
...
bankProcessor.process();
cryptoProcessor.process();
Also if you want to pass a string instead of class you can use Map
processorMap: Map<string, new () => PaymentProcessor> = new Map([
['crypto', CryptoProcessor],
['bank', BankProcessor],
]);
processorMap.get('crypto');
....
Can be tested here