javascript - typescript 如何输入 Promise.all()
问题描述
typescript 是如何键入 Promise.all() 在解析出来的值数组中,typescript 是如何能够推断出每一项的类型呢?我在 Promise.all() 的类型签名中只看到一个 Generic T,但为什么我能够传入解析为不同类型值的承诺?
详细地说,为什么我的 promiseAll 实现会抛出 typescript 类型错误,但内置的实现却像魔术一样工作?
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();
解决方案
具有 11 个重载的TypeScript 类型Promise.all
,但这种方法最多只允许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
重载似乎只支持参数中最多 9 个不同类型的元素values
。
您作为示例给出的代码与上面的第二个重载非常匹配,但具有相同的限制,因为它仅Promise
在传递给的数组中每个的类型相同时才有效Promise.all
。
如果您告诉 TypeScript 您将类型数组传递Promise<number | string>[]
给,您的示例将编译PromiseAll
,因为这样您的所有Promise
s 都将被视为具有相同的类型。当然,您返回的数组将是类型(number | string)[]
,并且您不知道哪个元素具有哪种类型。
推荐阅读
- java - Java ImageIO 正在读取 RGB 而不是 ARGB 数据
- excel - 如何计数然后查找?
- npm - 在本地和全局安装 npm 依赖项在执行命令行时会产生错误
- outlook-redemption - 是否可以在不处理项目的情况下复制文件夹结构?
- java - 生成契约契约:如何创建匹配任何东西的 PactDslJsonBody
- python - Python 正则表达式搜索返回正非整数 <1 作为空字符串
- tensorflow - 如何在每个时期打印一个张量
- go - 对于看似有效的 png,输入字节处的非法 base64 数据
- node.js - 在 Sequelize 中有一个关联
- powershell - 未保存在 PowerShell 中的变量