title: TypeScript: Adding dynamic fields to a class at runtime with type safety
body: <p>I'm converting some legacy JS code to TS, and have run into an interesting typing situation. There is a module system that is loading class instances at runtime onto named properties of an instance of another class, and am trying to figure out how to type the object:</p>
  <pre class="lang-js prettyprint-override"><code>class Module {
    public name: string;
  }
  
  class ThisModule extends Module {
    public name = 'thisModule';
  
    public log = () =&gt; {
      console.log('ThisModule called!');
    };
  }
  
  class ThatModule extends Module {
    public name = 'thatModule';
  
    public log = () =&gt; {
      console.log('ThatModule called!');
    };
  }
  
  interface IModule extends Module {}
  
  type ModulesInput = Module[];
  
  class Container {
    public init = (modules: ModulesInput) =&gt; {
      for (const module of modules) {
        this[module.name] = module;
      }
    };
  }
  
  const thisModule = new ThisModule();
  const thatModule = new ThatModule();
  
  const container = new Container&lt;ThisModule | ThatModule &gt;();
  
  const modules: ModulesInput = [
    thisModule,
    thatModule,
  ];
  container.init(modules);
  
  // Should not throw TS error
  container.thisModule.log();
  container.thatModule.log();
  
  // Should throw error (&quot;Property anythingElse does not exist on Container&quot;)
  container.anythingElse.log();
  </code></pre>
  <p>The problem is that TypeScript is not recognizing that <code>container.thisModule</code> or <code>container.thatModule</code> should exist. It says <code>TS2339: Property 'thisModule' does not exist on type 'Container'.</code> (and also for <code>thatModule</code>, the same).</p>
  <p>Is there a way to type this system? I have had some limited success so far adding multiple generics to the <code>Container</code> class (e.g. <code>type keys = 'thisModule' | 'thatModule'</code> and <code>type ModulesInUse = ThisModule | ThatModule</code>), but can TypeScript discover the names from the classes and dynamically learn that it should expect those keys on the <code>container</code> object to have types of their respective classes?</p>
  <p>Thanks in advance!</p>