title: Constraining type in Typescript generic to be one of several types
body: <p>I'm trying to constrain the input of a generic to be one of several types. The closest notation I've found is using union types. Here is a trivial example:</p>
  
  <pre><code>interface IDict&lt;TKey extends string | number, TVal&gt; { 
      // Error! An index signature parameter type must be 
      // a 'string' or a 'number'
      [key: TKey]: TVal; 
  }
  
  declare const dictA: IDict&lt;string, Foo&gt;;
  declare const dictB: IDict&lt;number, Foo&gt;;
  </code></pre>
  
  <p>What I'm looking for, in this example, is a way to say that <code>TKey</code> should be either <code>string</code> or <code>number</code>, but not the union of them.</p>
  
  <p>Thoughts?</p>
  
  <p>Note: This is a specific case of a broader question. For example, I have another case where I have a function that accepts <code>text</code> which can be either a <code>string</code> or <code>StructuredText</code> (parsed Markdown), transforms it, and returns exactly the corresponding type (not a subtype). </p>
  
  <pre><code>function formatText&lt;T extends string | StructuredText&gt;(text: T): T {/*...*/}
  </code></pre>
  
  <p>Technically I could write that as an overload, but that doesn't seem like the correct way.</p>
  
  <pre><code>function formatText(text: string): string;
  function formatText(text: StructuredText): StructuredText;
  function formatText(text) {/*...*/}
  </code></pre>
  
  <p>An overload also proves problematic, because it won't accept a union type:</p>
  
  <pre><code>interface StructuredText { tokens: string[] }
  
  function formatText(txt: string): string;
  function formatText(txt: StructuredText): StructuredText;
  function formatText(text){return text;}
  
  let s: string | StructuredText;
  let x = formatText(s); // error
  </code></pre>