title: TypeScript generics work when you call it but not in the function body?
body: <p>Say I have this example:</p>
  <pre class="lang-js prettyprint-override"><code>type Keys = 'one' | 'two';
  type Values&lt;T extends Keys&gt; = T extends 'one' 
    ? { id: 1, name: 'hello1' } 
    : T extends 'two' 
      ? { id: 2, value: 'hello2' }
        : never;
  
  type Fn = &lt;T extends Keys&gt;(key: T) =&gt; (value: Values&lt;T&gt;) =&gt; void;
  
  const fn: Fn = (key) =&gt; (value) =&gt; {
    if (key === 'one') {
      const name = value.name; // This throws compile error
    }
  }
  
  // Both of these `fn` calls correctly limit the `value` argument based on the `key`
  fn('one')({ id: 1, name: 'hello1' });
  fn('two')({ id: 2, value: 'hello2' });
  </code></pre>
  <p>Can someone explain to me <strong>why</strong> this setup <em>correctly limits</em> the allowed types for the <code>value</code> argument when invoking the <code>fn</code> method, but doesn't allow me to narrow <code>value</code> after using a Type Guard inside the <code>fn</code> implementation?</p>
  <p><a href="https://www.typescriptlang.org/play?ssl=18&amp;ssc=39&amp;pln=15&amp;pc=2#code/FAFwngDgpgBA0lMBnGBeGByA9gOyhmAH0xAHcsMBuUSWANQEMAbAVyiQB4AVGKADxBQcAExQJkAPjQwe-QSJTY8BYDBgB+GAG8YAS2EAuGAEYANDBwMAtlCMYAFlCZMsxggF8YqmEdkChoiTkKmpqmjr6RgBM5gBuzGx2js5YUR7eoT4WULFQAE7UNNAwAGI40ty8-grwiEgSABQA1oi+AJRoUg3xrLYwjL2cXBIdqFKxWPqFAMa4SCAwAGY4RmXSzYijXT1sW9reuoswG2BoqOhK+B1aGTCzOPMW1rDoO1AAdJY21GruwH-AZYNS4YNoNCKGEzmL59BxOFxuGDuNrUIEYMgUMEQ6JxBKw5IuNJIlHAQEsHDTEC6XAwJBYGwlcnTE52XBXIzdPFGbFQp42JLw1wePYTKZkilUml0hlMllBTEct7cvSQmIwJWYAmpYWddWTYSFRZMyXlaVQRkUuXiJDXLxqPJQEAsPLlTm9IwDNica0jXU3TKHY4tU7nC5s0H7TJqe6PGHSN6fZ4-UJ-X7-Um6HCCPKLBjTWAASTW-qDrUw4baiq52hVRjMfPxgsRyN1ooN3jl6OCleOGp5ao1cJSRJbYz1YoBMYWyxWMCL5XQJz2bt2foOR2BMIImfVeOutynDfjeMT328f3cQA" rel="nofollow noreferrer">Playground</a> - I have this playground with a few other attempts to make this work, but not success.</p>
  <p>Ultimately I'm trying to use something similar to this as a <code>useCallback</code> method in a React project where an <code>onChange</code> prop is set with the callback invoked with a key, then the event sends the value. Since I know the types of the event, I feel like this should be possible. Ex:</p>
  <pre class="lang-js prettyprint-override"><code>&lt;Component1 onChange={handleChange('key1')} /&gt;
  &lt;Component2 onChange={handleChange('key2')} /&gt;
  </code></pre>