'How do I create a new tuple from a variadic generic tuple in TypeScript?

Given:

class Foo {}
class Bar {}

interface QueryResult<T> {
  data: T;
}

function creatQueryResult<T>(data: T): QueryResult<T> {
  return {data};
}

function tuple<T extends any[]>(...args: T): T {
  return args;
}

I want to create and type a function using inferred types that accepts QueryResult[] or a tuple of QueryResults and a factory callback that picks data and invokes the callback like:

function createCompoundResult<T>(
  queryResults: T,
  callback: (queryResultDatas: ???<T>) => any
) {
  const datas = queryResults.map((queryResult) => queryResult.data);

  return callback(datas);
}

Note the ??? in the above code.

Usage:

const fooQueryResult = creatQueryResult(new Foo());
const barQueryResult = creatQueryResult(new Bar());

// Maybe using tuples are wrong?
const queryResults = tuple(fooQueryResult, barQueryResult);

createCompoundResult(
  queryResults,
  (datas) => {
    const [foo, bar] = datas;
    // foo should be inferred as Foo here and bar as Bar
  }
);

Maybe tuples are the wrong way to go? How would you solve it?

I'm a bit of a TypeScript newbie and I have a really hard time understanding stuff like keyof, extends keyof, { [K in keyof T]: { a: T[K] } } so if your solutions include arcane magic like this, please explain it to me like I'm 5 years old.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source