title: Inferring types of deeply nested object in Typescript
body: <p>I'm trying to create a function that safely looks up the property in deeply nested object (<code>theme</code> in this case). I should mention that I don't want to statically define its type because they are intended to be a subject to frequent change and thus use <code>typeof</code></p>
  
  <p>This functions accepts the object itself and 3 keys, but the problem is — I can't correctly infer types for all of them.</p>
  
  <pre class="lang-ts prettyprint-override"><code>const theme = {
      button: { margin: { sm: "sm" } },
      form: { padding: { lg: "lg" } }
  }
  
  type Theme = typeof theme
  
  type CompoName = keyof Theme;
  
  // styles of component with give key
  // { margin: ..., padding: ... }
  type CompoStyle&lt;C&gt; = C extends CompoName ? keyof Theme[C] : never;
  
  // string 
  // S = margin, padding
  type CompoStyleMod&lt;C, S&gt; = S extends keyof CompoStyle&lt;C&gt;
    ? CompoStyle&lt;C&gt;[S]
    : never;
  
  const getStyle = (
      t: Theme,
      name: CompoName,
      style: CompoStyle&lt;typeof name&gt;,
      mod: CompoStyleMod&lt;CompoName, typeof style&gt;
  ) =&gt; {
      return t[name][style][mod]
  }
  </code></pre>
  
  <p>The result of this in TypeScript 3.6.3:</p>
  
  <pre><code>Element implicitly has an 'any' type because expression of type '"margin" | "padding"' can't be used to index type '{ margin: { sm: string; }; } | { padding: { lg: string; }; }'.
  
    Property 'margin' does not exist on type '{ margin: { sm: string; }; } | { padding: { lg: string; }; }'.
  </code></pre>
  
  <p>Looks like it is not possible to look up union types with union types and some kind of inference required midway.</p>
  
  <p>Any ideas?</p>