When working with typescript, my goal is to instantiate a class by using its name as a string. After some research, I discovered the following approach:
const googlecommand = Object.create((Commands as any)['GoogleCommand'].prototype);
This line of code exists in a separate file from where GoogleCommand
is defined. It is important for "Command" to be a namespace in order for this method to work. While some resources suggest that it may be accessible through window
by default, that was not the case for me. Having all "Command" classes in a single file wrapped in a namespace would simplify things, but it complicates code organization especially when dealing with multiple commands.
Therefore, my objective now is to place each command in its own .ts file and then encapsulate them within a single namespace. To illustrate, here is the conceptual structure I envision (although it will not function correctly in its current state):
// GoogleCommand.ts
export namespace {
export class GoogleCommand extends AbstractCommand {
....
}
}
// BingCommand.ts
export namespace {
export class BingCommand extends AbstractCommand {
....
}
}
// CommandProcessor.ts
import { AbstractCommand } from './AbstractCommand';
import { Commands } from './GoogleCommand';
import { Commands } from './BingCommand'; // This will obviously conflict
// The value of commandName will be determined by an external config file so its actual content
// is unknown at this point, aside from being the name of one of the commands
let commandName;
commandName = 'GoogleCommand';
const googlecommand: AbstractCommand = Object.create((Commands as any)[commandName].prototype);
commandName = 'BingCommand';
const bingcommand: AbstractCommand = Object.create((Commands as any)[commandName].prototype);