title: Typescript object with conditional values based on key
body: <p>I'm trying to define a type for an object:</p>
  <pre><code>const width: Rule = {
    // regular keys with any name
    full: &quot;100%&quot;,
    half: &quot;50%&quot;,
  
    // special keys
    $px: [10, 50, 100],
    $rem: [1, 1.5, 2],
    $em: [1, 1.5, 2],
  }
  </code></pre>
  <p>Where <code>Array&lt;number&gt;</code> value can only be used with special keys (<code>'$px' | '$em' | '$rem'</code>) and <code>string</code> value only with regular ones.</p>
  <p>So I tried something like this:</p>
  <pre><code>export type Special = &quot;$px&quot; | &quot;$em&quot; | &quot;$rem&quot;;
  
  export type Rule&lt;K extends string&gt; = {
    [key: K]: K extends Special ? Array&lt;number&gt; : string;
  } 
  </code></pre>
  <p>But having an error at <code>[key: K]</code>:</p>
  <blockquote>
  <pre><code>(parameter) key: K extends string
  An index signature parameter type must be either 'string' or 'number'.ts(1023)
  </code></pre>
  </blockquote>
  <p>What am I doing wrong?</p>
  <p><strong>UPDATE:</strong></p>
  <p>The answer proposed in the comments doesn't work in my case, because I don't have a declared interface with known keys. I have a <code>Record&lt;string, string | Array&lt;number&gt;&gt;</code> instead and doing something like:</p>
  <pre><code>export type Rule = {
    [K in keyof Record&lt;string, any&gt;]: K extends Special ? Array&lt;number&gt; : string;
  };
  </code></pre>
  <p>gives an error on special keys:</p>
  <blockquote>
  <pre><code>(property) $px: number[]
  Type 'number[]' is not assignable to type 'string'.
  </code></pre>
  </blockquote>
  <p>So far I ended up with something like this:</p>
  <pre><code>export type Rule = Record&lt;string, string | Array&lt;number&gt;&gt; &amp; 
                     Partial&lt;Record&lt;Special, Array&lt;number&gt;&gt;;
  </code></pre>
  <p>But obviously it allows to set <code>Array&lt;number&gt;</code> on regular keys which is not ideal.</p>