title: Generic type wrapping in TypeScript for tuples
body: <p>I need to add a type declaration to a function which maps elements of a tuple <code>[Foo&lt;A&gt;, Foo&lt;B&gt;, ...]</code> to a function <code>() =&gt; [A, B, ...]</code>. How can I achieve this in TypeScript?</p>
  
  <p>This example is structurally similar to the relevant part of the application:</p>
  
  <pre><code>interface SomethingWithAValue&lt;T&gt; { value: T; }
  
  function collect(array) {
    return () =&gt; array.map(a =&gt; a.value);
  }
  </code></pre>
  
  <p>This returns a tuple of the values associated with each object. What would the type declaration for <code>collect</code> look like?</p>
  
  <p>Pseudocode:</p>
  
  <pre><code>function collect&lt;[SomethingWithAValue&lt;T&gt;...](array: [SomethingWithAValue&lt;T&gt;...]): () =&gt; [T...];
  </code></pre>
  
  <hr>
  
  <p>Update in response to jonrsharpe's suggestion:</p>
  
  <pre><code>interface SomethingWithAValue&lt;T&gt; { value: T; }
  
  function collect&lt;T&gt;(array: SomethingWithAValue&lt;T&gt;[]): () =&gt; T[] {
    return () =&gt; array.map(a =&gt; a.value);
  }
  
  type myTupleType = [string, number];
  
  let somethings: [SomethingWithAValue&lt;string&gt;, SomethingWithAValue&lt;number&gt;];
  somethings = [{ value: 'foo' }, { value: 5 }];
  
  let fn: () =&gt; myTupleType = collect(somethings);
  </code></pre>
  
  <p>This does not work:</p>
  
  <pre><code>Argument of type '[SomethingWithAValue&lt;string&gt;, SomethingWithAValue&lt;number&gt;]' is not assignable to parameter of type 'SomethingWithAValue&lt;string&gt;[]'.
    Types of property 'pop' are incompatible.
      Type '() =&gt; SomethingWithAValue&lt;string&gt; | SomethingWithAValue&lt;number&gt;' is not assignable to type '() =&gt; SomethingWithAValue&lt;string&gt;'.
        Type 'SomethingWithAValue&lt;string&gt; | SomethingWithAValue&lt;number&gt;' is not assignable to type 'SomethingWithAValue&lt;string&gt;'.
          Type 'SomethingWithAValue&lt;number&gt;' is not assignable to type 'SomethingWithAValue&lt;string&gt;'.
            Type 'number' is not assignable to type 'string'.
  </code></pre>