title: Typescript: object property type when indexed by narrowed keyof generic type
body: <p>I need to supply an adapter function that takes an object and returns a value of a given type or types.  I am trying to write a generic function that will generate such an adapter function given an object property name, where the property names are restricted to properties whose value is of the given type(s).</p>
  
  <p>For example, consider the simple case of numeric properties:</p>
  
  <pre class="lang-js prettyprint-override"><code>type Adapter&lt;T&gt; = (from: T) =&gt; number
  </code></pre>
  
  <p>I think I want to do something like:</p>
  
  <pre class="lang-js prettyprint-override"><code>type NumberFields&lt;T&gt; = {[K in keyof T]: T[K] extends number ? K : never}[keyof T]
  
  function foo&lt;T&gt;(property: NumberFields&lt;T&gt;) {
      return function(from: T) {
          return from[property]
      }
  }
  </code></pre>
  
  <p>TypeScript is happy enough when the argument to <code>NumberFields</code> is not generic:</p>
  
  <pre class="lang-js prettyprint-override"><code>interface Foo {
      bar: number
  }
  
  function ok&lt;T extends Foo, K extends NumberFields&lt;Foo&gt;&gt;(property: K): Adapter&lt;T&gt; {
      return function(from: T): number {
          return from[property] // ok
      }
  }
  </code></pre>
  
  <p>However, in the generic case TypeScript doesn't want to recognise that <code>from[property]</code> can only possibly be a number:</p>
  
  <pre class="lang-js prettyprint-override"><code>function bar&lt;T, K extends NumberFields&lt;T&gt;&gt;(property: K): Adapter&lt;T&gt; {
      return function(from: T): number {
          return from[property] // error: Type 'T[K]' is not assignable to to type 'number'
      }
  }
  
  function baz&lt;T, K extends NumberFields&lt;T&gt;&gt;(property: K): Adapter&lt;T&gt; {
      return function(from: T): T[K] { // error: Type '(from: T) =&gt; T[K]' is not assignable to type 'Adapter&lt;T&gt;'
          return from[property]
      }
  }
  </code></pre>
  
  <p>Why does it work when the type is constrained, but not in the truly generic case?</p>
  
  <p>I have looked at many SO questions, of which <a href="https://stackoverflow.com/questions/50761836/narrowing-typescript-index-type">Narrowing TypeScript index type</a> seemed the closest to what I want, but a type guard isn't useful here since the type should be generic.</p>