title: Typescript Generic Array to Record function with proper type restrictions
body: <p>I'm trying to write a generic function that takes an <code>array: T[]</code> and a selector <code>K</code> and returns a <code>Record&lt;T[K], T&gt;</code> that maps each element in the array from one of its properties to itself.</p>
  <p>e.g.</p>
  <pre><code>const input1 = [{ name: &quot;Alice&quot; }, { name: &quot;Bob&quot; }];
  const output1: Record&lt;string, { name: string }&gt; = toRecord(input1, &quot;name&quot;);
  // { Alice: { name: &quot;Alice&quot; }, Bob: { name: &quot;Bob&quot; } }
  
  // -----------------------------------------------------------------
  enum Name {
    Alice = &quot;Alice&quot;,
    Bob = &quot;Bob&quot;
  }
  const input2 = [{ name: Name.Alice }, { name: Name.Bob }];
  const output2: Record&lt;Name, { name: Name }&gt; = toRecord(input2, &quot;name&quot;);
  // { Alice: { name: &quot;Alice&quot; }, Bob: { name: &quot;Bob&quot; } }
  
  // -----------------------------------------------------------------
  interface Person {
    id: number;
    name: string;
    sibling?: Person;
  }
  const input3: Person[] = [{ id: 1, name: &quot;Alice&quot; }, { id: 2, name: &quot;Bob&quot; }];
  const output3: Record&lt;number, Person&gt; = toRecord(input3, &quot;id&quot;);
  // { 1: { id: 1, name: &quot;Alice&quot; }, 2: { id: 2, name: &quot;Bob&quot; } }
  </code></pre>
  <p>I can't figure out how to restrict the type of the selector property <code>K</code> so that <code>T[K]</code> has a type a <code>Record</code> accepts as keys i.e. <code>string | number | symbol</code>.</p>
  <p>This is what I have so far:</p>
  <pre><code>export function toRecord&lt;T, K extends keyof T&gt;(
    array: T[], 
    selector: K
  ): Record&lt;T[K], T&gt; {
    return array.reduce(
      (acc, item) =&gt; (acc[item[selector]] = item, acc), 
      {} as Record&lt;T[K], T&gt;
    )
  }
  </code></pre>
  <p>But this gives me the following error at <code>T[K]</code>:</p>
  <blockquote>
  <pre><code>Type 'T[K]' does not satisfy the constraint 'string | number | symbol'.      
   Type 'T[keyof T]' is not assignable to type 'string | number | symbol'.
     Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string | number | symbol'.
       Type 'T[string]' is not assignable to type 'string | number | symbol'.
         Type 'T[string]' is not assignable to type 'symbol'.
           Type 'T[keyof T]' is not assignable to type 'symbol'.
             Type 'T[K]' is not assignable to type 'symbol'.
               Type 'T[keyof T]' is not assignable to type 'symbol'.
                 Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'symbol'.
                   Type 'T[string]' is not assignable to type 'symbol'.(2344)
  </code></pre>
  </blockquote>
  <p>How can I restrict <code>K</code> so that <code>T[K]</code> is <code>string | number | symbol</code>?</p>
  <p><a href="https://stackblitz.com/edit/typescript-amxpca" rel="nofollow noreferrer"><strong>Stackblitz</strong></a></p>