title: TypeScript: Create typed Record without explicitly defining the keys
body: <p>What I'd like to do is to create an object which is a Record of a certain interface and have TypeScript be able to infer the keys based on what's in my object. I've tried a few things, none of which do exactly what I'm looking for.</p>
  <pre><code>interface Person {
    firstName:string
  }
  
  const peopleObj = {
    Jason: {
      firstName: &quot;Jason&quot;
    },
    Tim: {
      firstName: &quot;Tim&quot;
    }
  } as const;
  
  console.log(peopleObj);
  </code></pre>
  <p>Here, if you look at peopleObj, TypeScript knows the exact keys because of the <code>as const</code>. The problem here is I'm not enforcing each object to be a <code>Person</code>. So I tried this next:</p>
  <pre><code>const peopleObj: Record&lt;string, Person&gt; = {
    Jason: {
      firstName: &quot;Jason&quot;
    },
    Tim: {
      firstName: &quot;Tim&quot;
    }
  } as const;
  </code></pre>
  <p>Here, each object has to be a <code>Person</code> because of the <code>Record</code> defined, but TypeScript loses its ability to know all of the keys because now they are just <code>string</code> instead of the constants <code>'Jason' | 'Tim'</code>, and this is the crux of the issue. I know I could explicitly use <code>'Jason' | 'Tim'</code> in place of my <code>string</code> type, but this is a fairly large object in real life and updating that type explicitly every time I add to it or remove from it is getting to be tedious.</p>
  <p>Is there a way to have the best of both worlds, where I can have TypeScript infer the keys in the object just based solely on what's in the object? I have found <em>a</em> way, although it's not super clean and I feel like there's likely a better way:</p>
  <pre><code>interface Person {
    firstName:string
  }
  
  type PeopleType&lt;T extends string&gt; = Record&lt;T, Person&gt;;
  
  const peopleObj: Record&lt;string, Person&gt; = {
    Jason: {
      firstName: &quot;Jason&quot;
    },
    Tim: {
      firstName: &quot;Tim&quot;
    }
  } as const;
  
  const People:Record&lt;keyof typeof peopleObj, Person&gt; = peopleObj;
  
  console.log(People.Jason);
  </code></pre>