能否构建更优Promise.all?TypeScript编译时能否推导解包泛型?
实现方案
完全可以实现,TypeScript的映射类型和泛型推导就能满足需求,不需要Rank-2 Types。以下是具体实现:
类型定义与函数实现
// 工具类型:提取对象中每个Promise的resolve结果类型 type ResolvedPromises<T extends Record<string, Promise<any>>> = { [K in keyof T]: T[K] extends Promise<infer U> ? U : never; }; function resolveAll<T extends Record<string, Promise<any>>>(obj: T): Promise<ResolvedPromises<T>> { const entries = Object.entries(obj) as [keyof T, T[keyof T]][]; return Promise.all(entries.map(([_, promise]) => promise)) .then(results => { const resolvedObj = {} as ResolvedPromises<T>; entries.forEach(([key], index) => { resolvedObj[key] = results[index]; }); return resolvedObj; }); }
验证类型推导
你的示例代码可直接正常编译,类型推导完全符合预期:
const result: number = await resolveAll({ aNumber: Promise.resolve(1), anObject: Promise.resolve({foo: 1, bar: "baz"}), }).then(({ aNumber, // 类型自动推导为number anObject: { foo } // 类型自动推导为{foo: number, bar: string} }) => aNumber + foo);
原理说明
ResolvedPromises<T>是映射类型,遍历输入对象的每个键K,通过条件类型的infer U语法提取对应Promise的resolve值类型。- 函数
resolveAll接收泛型参数T(约束为键是字符串、值是Promise的对象),返回Promise<ResolvedPromises<T>>。TypeScript会自动推导T的具体结构,进而精准生成最终resolved对象的类型。
这种实现完全基于TypeScript原生类型系统特性,无需依赖Rank-2 Types即可保留每个键对应的类型信息。
内容的提问来源于stack exchange,提问作者wvandaal
相关产品推荐
相关产品推荐

