title: Generics: use type as object key in typescript
body: <p>When using a type that contains strings that are Piped <code>|</code> together it means that either one of those strings can be used as value. In the example below <code>TFoo</code> contains those three values, <code>foo</code>, <code>bar</code> and <code>baz</code>.</p>
  
  <p>Using the <code>[P in TFoo]</code> we can tell typescript, that any of those strings can be used as key in the object of type TDirect. VSCode helps with code completion, we can successfully build up <code>direct</code>, no errors.</p>
  
  <p>In our case <code>TFoo</code> is not always the same, in reality it will contain different event names depending of the microservice. So we tried to use generics as seen in TGeneric. And that is where the T is underlined an we get the following error:</p>
  
  <pre><code>Type 'T' is not assignable to type 'string | number | symbol'.
    Type 'T' is not assignable to type 'symbol'.ts(2322)
  </code></pre>
  
  <p>What is strange though is that VSCode seems to understand what we are trying to do, it still helps with intellisense and correctly highlights <code>wrong: "value"</code> as incorrect.</p>
  
  <p>A <code>tsc</code> will result in compiler errors (see above). When moving TGeneric in its own file and when using e.g. <code>ts-node --files src</code> (assuming all files live in src) everything runs fine.</p>
  
  <p>So we are currently having the problem that we get what we want, as we have intellisense and the code still runs with ts-node. But we actually have a bad feeling about the strange behaviour.</p>
  
  <p>Maybe anyone has a bullet-proof solution?</p>
  
  <pre class="lang-js prettyprint-override"><code>type TFoo = "foo" | "bar" | "baz";
  
  
  type TDirect = { [P in TFoo]?: any };
  const direct: TDirect = {
    bar: "baz"
  }
  
  
  type TGeneric&lt;T&gt; = { [P in T]?: any };
  const generic: TGeneric&lt;TFoo&gt; = {
    bar: "baz",
    wrong: "value"
  }
  </code></pre>