打字稿如何输入Promise.all()

How does typescript type Promise.all()

typescript如何打字Promise.all() 在已解析的值数组中,打字稿如何能够推断出每个项目的类型?我在 Promise.all() 的类型签名中只看到一个通用 T,但为什么我能够传递解析为不同类型值的承诺?

详细说明一下,为什么我的 promiseAll 实现抛出打字稿类型错误,但内置的却像魔术一样工作?

const promiseAll = function<T>(promises: Promise<T>[]): Promise<T[]> {
  const results: T[] = [];
  let completedCount = 0;
  return new Promise(function (resolve, reject) {
    promises.forEach(function(promise, index) {
      promise.then(function (value) {
        results[index] = value;
        completedCount += 1;
        if(completedCount === promises.length) {
          resolve(results);
        }
      }).catch(function (error) {
        reject(error);
      });
    });
  });
}

const promise1 = new Promise<number>(resolve => setTimeout(() => { resolve(1) }, 500));
const promise2 = new Promise<string>(resolve => setTimeout(() => { resolve("a") }, 500));



async function main() {
    const [value1, value2] = await Promise.all([promise1, promise2]);
    const [myValue1, myValue2] = await promiseAll([promise1, promise2]);
}

main();

TypeScript 类型 Promise.all 有 11 个重载,但这种方法只允许最多传入有限数量的 PromiseLike 不同类型的对象。其中一个重载能够处理一个但是,任何长度的数组都填充了一致类型的 PromiseLike 对象。下面是两个重载的例子:

Promise.all<T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<[T1, T2, T3, T4]>
Promise.all<T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>

具有独立类型参数的 Promise.all 重载似乎只支持 values 参数中最多 9 个不同类型的元素。

您作为示例给出的代码非常接近上面的第二个重载,但具有相同的限制,因为它只有在数组中每个 Promise 的类型传递给 Promise.all也是一样。

如果您告诉 TypeScript 您正在将类型 Promise<number | string>[] 的数组传递给 PromiseAll,那么您的示例将会编译,因为这样您的所有 Promise 都将被视为具有相同的类型。当然,您返回的数组是 (number | string)[] 类型,您不知道哪个元素具有哪种类型。