title: Typescript object with keys of union type but with non uniform value types
body: <p>TLDR, what I'm trying to do is create an (object) type, where the key types are matching a literal-union type, but the value types are all different.</p>
  <p>Consider the following scenario. We have a set if <code>PluginId</code>s (union of string literal types). Each of these represent a plugin (what a plugin is is irrelevant). I'd like to create an object type, where the keys match this union of string literal, and the values are a type unique for the given plugin.</p>
  <pre><code>// Union of literal types
  export type PluginId = 'cat' | 'dog' | 'racoon'
  
  /**
   * - false means plugin is off
   * - true means plugin is on with default config
   * - custom configuration object means on, with custom config
   */
  export type Config&lt;T = {}&gt; = boolean | Partial&lt;T&gt;
  
  // Custom config objects, not every plugin has one
  export type DogPluginConfig = { woof: boolean }
  export type CatPluginConfig = { meow: boolean }
  
  // I'd like each key to be a PluginId here, and I'd like the compiler to enforce this.
  export type Configs = {
    cat?: Config&lt;CatPluginConfig&gt;
    dog?: Config&lt;DogPluginConfig&gt;
    racoon?: Config
  }
  
  export function instantiatePlugins(configs: Configs): Plugin[] {
    // doesn't matter
  }
  </code></pre>
  <p>This is what I've got so far, but as it stands currently, there is no link between the keys of <code>Configs</code> and <code>PluginId</code>.</p>
  <p>I've tried utilizing a <code>Record</code> type, something like:</p>
  <pre><code>export type Configs = Partial&lt;Record&lt;PluginId, Config&gt;&gt; &amp; {
    cat?: Config&lt;CatPluginConfig&gt;
    dog?: Config&lt;DogPluginConfig&gt;
  }
  </code></pre>
  <p>This does halfway what I want to do, but it doesn't enforce that the keys I define on the type after <code>&amp;</code> match <code>PluginId</code>.</p>
  <p>Is there any way I could do what I want?</p>