title: Keyof as generic
body: <p>I'm trying to force someone that want to update an object to pass a the key to update with a correct value type.
  As seen in the <a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAChBOBnA9gOygXigbwFBQKlQEMBbCALikWHgEtUBzAbn0OMcqIFdSAjBKwC+rXADNuqAMbA6aKNzAATYsAgAeACpQIADzWoliKAGsIIZGNgIUqAHwAKZPUZU4SNABpT5qpu8AbsQANtxc7rYA2poAugCUbjbyeIRQdFYOZiCYGFgARCTkeXE4bKkE8BDA3PDoKeUNAHTNznSMnmUNhIVcQaEQnalCnUI6wYjQ6VCZ5jn5HBDFpV1QldW1yyuEzY2t7YNdC1R9YQcEw0NjE5sNazXoeyO4w7jBVQqoJqjIAO6oEfIsPUCD0qHkAKqfb5-PIdVJHKAATmRz1Yki+v3+SXQWEUKjUDnR0KxHlQ3jyC1hUAAjAAGOJoqGYgE4hTKVQQQlMv4s8mU8nUgCsxVYQA" rel="nofollow noreferrer">playground</a> typescript seems unable to understand that if the <code>key</code> has a certain value the <code>value</code> variable has a correct type.
  While calling the function the type checking is correct and don't allow to pass inconsistent values with the key.</p>
  <pre><code>type Person = {
      name: string;
      age: number;
  };
  
  function update&lt;T extends keyof Person&gt;(orig: Person, key: T, value: Person[T]): Person {
      if (key === &quot;name&quot;) {
          return {
              ...orig,
              name: value  // Error: number not assignable to string
          }
      } else if (key === &quot;age&quot;) {
          return {
              ...orig,
              age: value  // Error: string not assignable to number
          }
      } else {
          return orig
      }
  }
  
  let unknownPerson = {
      name: &quot;Unknown&quot;,
      age: 999
  };
  unknownPerson = update(unknownPerson, &quot;age&quot;, 10);
  unknownPerson = update(unknownPerson, &quot;age&quot;, &quot;15&quot;);  // Ok expected number
  </code></pre>