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

TypeScript中Promise.allSettled结合reduce的类型安全处理问题

解决Promise.allSettled结合reduce时的TypeScript类型问题

先定义各天气数据的基础接口,明确类型边界:

interface HourlyForecast { /* 逐小时预报字段定义 */ }
interface TenDayForecast { /* 十日预报字段定义 */ }
interface AirPollution { /* 空气污染数据字段定义 */ }
interface UVIndex { /* 紫外线指数字段定义 */ }
interface CurrentWeather { /* 当前天气字段定义 */ }

方案一:为Promise.allSettled结果分配对应类型

利用TypeScript的元组类型特性,让Promise.allSettled返回的结果数组每个位置对应各自Promise的返回类型,而非模糊的联合类型。

// 将并发请求的Promise定义为元组(as const 强制TypeScript识别为固定长度的元组)
const weatherPromises = [
  fetchHourlyForecast(), // Promise<HourlyForecast>
  fetchTenDayForecast(), // Promise<TenDayForecast>
  fetchAirPollution(), // Promise<AirPollution>
  fetchUVIndex(), // Promise<UVIndex>
  fetchCurrentWeather() // Promise<CurrentWeather>
] as const;

// 执行allSettled,此时results的类型是对应位置的PromiseSettledResult元组
const results = await Promise.allSettled(weatherPromises);

// 处理单个结果时,通过status判断后直接获取类型安全的value
if (results[0].status === 'fulfilled') {
  const hourlyData = results[0].value; // 类型自动推断为HourlyForecast
}

方案二:在reduce中正确约束类型

先定义最终结构化数据的类型,再通过索引映射或switch分支让TypeScript准确识别每个结果的类型,避免any。

方式1:用映射数组关联索引与字段

// 定义最终要生成的结构化数据类型
interface StructuredWeatherData {
  hourly?: HourlyForecast;
  tenDay?: TenDayForecast;
  airPollution?: AirPollution;
  uvIndex?: UVIndex;
  current?: CurrentWeather;
}

// 映射索引与目标字段的对应关系(as const 固定key的类型)
const fieldMap = [
  { key: 'hourly' as const },
  { key: 'tenDay' as const },
  { key: 'airPollution' as const },
  { key: 'uvIndex' as const },
  { key: 'current' as const },
] as const;

// 执行reduce,明确累加器类型为StructuredWeatherData
const structuredData = fieldMap.reduce<StructuredWeatherData>((acc, { key }, index) => {
  const result = results[index];
  if (result.status === 'fulfilled') {
    // TypeScript会根据key自动匹配对应的类型,无需断言any
    acc[key] = result.value;
  }
  // 可添加rejected状态的错误处理逻辑
  return acc;
}, {} as StructuredWeatherData);

方式2:通过switch分支匹配索引

const structuredData = results.reduce<StructuredWeatherData>((acc, result, index) => {
  if (result.status !== 'fulfilled') return acc;
  
  switch (index) {
    case 0:
      acc.hourly = result.value; // value类型自动推断为HourlyForecast
      break;
    case 1:
      acc.tenDay = result.value; // value类型自动推断为TenDayForecast
      break;
    case 2:
      acc.airPollution = result.value; // value类型自动推断为AirPollution
      break;
    case 3:
      acc.uvIndex = result.value; // value类型自动推断为UVIndex
      break;
    case 4:
      acc.current = result.value; // value类型自动推断为CurrentWeather
      break;
  }
  return acc;
}, {} as StructuredWeatherData);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:47:29