title: Can someone break down the steps of transforming a callback function into a async/await with the proper typing to correctly infer the return type?
body: <p>My problem is easy in javascript, I just want to wrap a callback fn and turn it into a asyn/await fn, like so:</p>
  <pre><code>function awaitify(func, ...args) {
    return new Promise((resolve, reject) =&gt; {
      func(...args, (err, value) =&gt; {
        if (err) {
          reject(err);
        }
        else {
          resolve(value);
        }
      });
    });
  }
  </code></pre>
  <p>Usage (typescript)
  This is just an arbitrary example of a callback fn, it could be any fn that follows teh cb model of <code>(...args, (err, value) =&gt; {});</code></p>
  <pre><code>function foo(a: string | null, b: number | null, c: string[] | null, callback: (err: Error | null, value: string | number | string[]) =&gt; void) {
    if (a) {
      callback(null, a);
    } else if (b) {
      callback(null, b);
    } else if (c) {
      callback(null, c);
    } else {
      callback(new Error(&quot;error&quot;));
  
    }
  }
  
  // Here I would expect result to know it's an array type
  const result = await awaitify(foo, null, null, [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]);
  </code></pre>
  <p>My approach:</p>
  <pre><code>type Head&lt;T extends any[]&gt; = T extends  [...infer Head, any] ? Head : any[];
  
  export function awaitify&lt;F extends (...args: any[]) =&gt; any&gt;(func: F, ...args: Head&lt;Parameters&lt;F&gt;&gt;) {
    return new Promise((resolve, reject) =&gt; {
      func(...args, (err: Error | null, value: ReturnType&lt;F&gt;) =&gt; {
        if (err) {
          reject(err);
        } else {
          resolve(value);
        }
      });
    });
  }
  </code></pre>
  <p>It is a collection of my own work and a bunch of other stackoverflow answers. I understand it to a point, but not entirely. This works like 90% of the way, but it doesn't infer the correct return type of the promise given any arbitrary callback function</p>
  <p>Can someone break down the steps and explain them in detail so I understand?</p>