You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何将「属性为Promise的对象」类型转换为「属性为Promise解析后值的对象」类型?

实现Promise对象的类型安全解析

当然可以做到!这其实是TypeScript泛型和工具类型的经典应用场景,正好能满足你保持类型安全的需求。

第一步:定义类型转换工具

我们需要一个泛型类型,把输入对象中每个Promise类型的属性,转换成其解析后的结果类型。TypeScript 4.5+提供的Awaited工具类型可以完美帮我们提取Promise的解析值,结合映射类型就能实现这个转换:

type ResolvedPromiseObject<T> = {
  [K in keyof T]: Awaited<T[K]>;
};

这个类型的作用很直观:

  • 遍历输入类型T的所有键K
  • 对每个键对应的属性值T[K],用Awaited提取出Promise最终resolve的类型
  • 最终生成一个和原对象结构完全一致,但属性值都是解析后类型的新类型

第二步:完善函数的返回类型与实现

接下来我们把这个类型应用到你的函数中,同时添加必要的类型约束和安全断言,让TypeScript能正确推断类型:

type ResolvedPromiseObject<T> = {
  [K in keyof T]: Awaited<T[K]>;
};

export async function resolveAllObject<T extends Record<string, Promise<any>>>(
  promiseObject: T
): Promise<ResolvedPromiseObject<T>> {
  // 初始断言为目标类型,因为我们后续会逐个赋值所有属性
  const resolvedPromiseObject = {} as ResolvedPromiseObject<T>;
  
  for (const key in promiseObject) {
    // 确保只处理对象自身的属性(避免遍历原型链)
    if (Object.prototype.hasOwnProperty.call(promiseObject, key)) {
      resolvedPromiseObject[key] = await promiseObject[key];
    }
  }
  
  return resolvedPromiseObject;
}

关键细节说明:

  • 泛型约束:T extends Record<string, Promise<any>>确保传入的参数必须是一个所有属性都是Promise的对象,避免传入不符合要求的参数导致类型错误。
  • 类型断言:{} as ResolvedPromiseObject<T>是必要的,因为初始空对象的类型是{},TypeScript无法自动推断它会被填充成目标类型,而我们明确知道后续会赋值所有属性,所以这个断言是安全的。
  • Awaited的优势:相比手动写条件类型T extends Promise<infer U> ? U : T,Awaited还能处理嵌套Promise(比如Promise<Promise<number>>)的情况,鲁棒性更强。

使用示例

我们用你提供的IPromiseObject来测试这个函数:

interface IPromiseObject {
  promiseA: Promise<number>;
  promiseB: Promise<string>;
}

async function testResolveAll() {
  const promiseObj: IPromiseObject = {
    promiseA: Promise.resolve(42),
    promiseB: Promise.resolve("TypeScript")
  };
  
  const resolvedObj = await resolveAllObject(promiseObj);
  // resolvedObj的类型自动推断为:{ promiseA: number; promiseB: string }
  
  // 这里的操作完全是类型安全的,TypeScript会提供正确的代码提示
  console.log(resolvedObj.promiseA.toFixed(1)); // 42.0
  console.log(resolvedObj.promiseB.toUpperCase()); // TYPESCRIPT
}

这样就能完美实现你想要的效果:解析Promise对象时全程保持类型安全,函数返回的类型和你期望的IResolvedPromiseObject完全一致。

内容的提问来源于stack exchange,提问作者Neidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:17:34