1

I am creating a solution in TypeScript/Javascript with an extension mechanism. The extensions will all be classes extending a provided abstract class and a configuration file will contain the class name and JSON to pass to the constructor. The extensions to be loaded will be defined in a configuration file.

However, I can't find a way to instantiate an instance of a class from the name of the class.

MarkE
  • 123
  • 8
  • Sounds like an antipattern to me. You cannot instantiate classes from strings in javascript. – Code Spirit Nov 13 '22 at 00:15
  • 1
    I agree it has a bit of a smell, but you could key an object by the class names with the relevant constructors assigned as values. – pilchard Nov 13 '22 at 00:21
  • For past projects when I've needed to do this, I've switched my configuration format to just regular JavaScript files. The downside with this is that it doesn't interop with other languages, so there's a tradeoff, but something to think about. Otherwise, what's recommended by @pilchard is solid. – Brad Nov 13 '22 at 00:24
  • See also https://stackoverflow.com/q/15338610/65694 – Alex Nolasco Nov 13 '22 at 00:35
  • That's a good duplicate @AlexNolasco The use of namespace via import offers the same functionality as my suggestion but the implicit nature of it is nice and clean. – pilchard Nov 13 '22 at 00:38

2 Answers2

2

You could key an object by the class names with the relevant constructors assigned as values.

class Class1 {
  constructor(val) {
    this.val = val;
  }
}

const classes = {
  Class1
}

const class1Instance = new classes["Class1"]('val1');

console.log(class1Instance.val)
pilchard
  • 12,414
  • 5
  • 11
  • 23
-1

This is an example of instantiating the class object using the string class name. But it looks pretty unsafe and weird to me.

class c1 {
  constructor(m) {
    this.message = m;
  }
  showme() {
    console.log(`It's class c1! Message: ${this.message}.`);
  }
}

const className = 'c1';
const constructorParams = '"instance B of class c1"';

const b = eval(`new ${className}(${constructorParams })`);
b.showme();
Alexey Zelenin
  • 710
  • 4
  • 10