How can one constrain a typescript generic to be an indexer?
<p>In typescript you can index into an object using only a <code>string</code>, <code>number</code> or <code>symbol</code>.</p>

<p>I want to have a generic that allows the generic parameters to be used as indexes.</p>

<pre><code>function foo&lt;T extends number|string&gt;(a: T): void {
    let x: any = {};
    x[a] = 42; // Error: an index expression argument must be of type...
}
</code></pre>

<p>If I cast to a <code>number|string</code>, it compiles:</p>

<pre><code>function foo&lt;T extends number|string&gt;(a: T): void {
    let x: any = {};
    let i: number|string = a;
    x[i] = 42; // OK
}
</code></pre>

<p>So the type checker is smart enough to know that if <code>T</code> extends <code>number|string</code> then I can assign it to a <code>number|string</code> (which I can then can use to index into an object) but for some reason it won't let me index with a <code>T</code> directly.</p>

<p>Is there a way to specify in the generic constraint that the type passed can be used as an indexer?</p>

<p><em>Note:</em> I'm using a generic and not <code>number|string</code> directly because I want to constrain the generic to accept only values from a specific <code>enum</code> or a <em>string literal union</em>.</p>

<p><strong>Edit:</strong> A more compelling example (and closer to what I'm really trying to do), is this:</p>

<pre><code>// The following line fails to compile even though Key is number | string
type Dictionary&lt;Key extends number | string, Value&gt; = { [index: Key]: Value }; 

// Had it compiled I would expect the following behaviour
type Answer = "yes" | "no" | "maybe";
let grades = {} as Dictionary&lt;Answer, number&gt;;  

grades["yes"] = 10;
grades["nope"] = 5; // Should be an error "nope" is not assignable to Answer
</code></pre>