title: Generics in nested TypeScript function
body: <p>I want to write a TypeScript function that accepts only certain strings, which are the property names of a specified type, but these properties must have a type of <code>string</code>, <code>number</code> or <code>Date</code>. This function returns another function that accepts the original object (of which the property names were selected) and returns the specified property (actually it does something else, but this is the simplest case that produces the same problem)</p>
  <p>I tried it like this</p>
  <pre class="lang-js prettyprint-override"><code>&quot;use strict&quot;;
  type InstancePropertyNames&lt;T, I&gt; = {
      [K in keyof T]: T[K] extends I ? K : never;
  }[keyof T];
  type StringPropertyNames&lt;T&gt; = InstancePropertyNames&lt;T, string&gt;;
  type NumberPropertyNames&lt;T&gt; = InstancePropertyNames&lt;T, number&gt;;
  
  function doSomething&lt;T extends object&gt;(
      key:
          | StringPropertyNames&lt;T&gt;
          | NumberPropertyNames&lt;T&gt;
          | InstancePropertyNames&lt;T, Date&gt;
  ) {
      return function(obj: T) {
          const res = obj[key];
          return res;
      }
  }
  function doSomethingEasy&lt;T extends object&gt;(
      obj: T,
      key:
          | StringPropertyNames&lt;T&gt;
          | NumberPropertyNames&lt;T&gt;
          | InstancePropertyNames&lt;T, Date&gt;
  ) {
      const res = obj[key];
      return res;
  }
  
  type Test = {
      asdf: string;
      foo: number;
      bar: boolean;
      qux: Date;
  };
  
  const test: Test = {
      asdf: &quot;asdf&quot;,
      foo: 42,
      bar: true,
      qux: new Date()
  }
  
  const res = doSomething&lt;Test&gt;(&quot;asdf&quot;)(test);
  console.log(res);
  const resEasy = doSomethingEasy(test, &quot;asdf&quot;);
  console.log(resEasy);
  </code></pre>
  <p><a href="https://tsplay.dev/kNrD0W" rel="nofollow noreferrer">TypeScript Playground</a></p>
  <p>The problem is now that the type of <code>res</code> inside the nested function is something complex (instead of simply <code>number | string | Date</code>), also in <code>doSomethingEasy</code>. Is there any way to simplify the type of the property in the nested function to the primitive types?</p>