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

使用条件类型处理Promise返回类型:API调用类型推导异常

解决方案:MongoDB API 类型推导问题

问题根源

你的问题出在泛型参数的约束范围和条件类型的推导逻辑上:当泛型T被约束为boolean时,TypeScript会将其解析为包含true和false的联合类型,导致Schema<T>最终推导为{prop1: string} | {prop1: 对象}的联合类型,而非你期望的单一类型。

方案1:使用函数重载(推荐)

函数重载能明确对应不同参数值的返回类型,避免联合类型的歧义,是最直观可靠的解决方式:

// 基础类型定义
type ObjectId = string;
type PopulatedProp = { id: ObjectId; name: string };

// 拆分两种状态的Schema
type UnpopulatedSchema = { prop1: ObjectId };
type PopulatedSchema = { prop1: PopulatedProp };

// 函数重载声明
async function callApi(): Promise<UnpopulatedSchema[]>;
async function callApi(populate: false): Promise<UnpopulatedSchema[]>;
async function callApi(populate: true): Promise<PopulatedSchema[]>;

// 函数实现
async function callApi(populate: boolean = false): Promise<(UnpopulatedSchema | PopulatedSchema)[]> {
  // 模拟API调用逻辑
  const res = await fetch('/api/data');
  return res.json();
}

// 调用示例
const unpopulatedData = callApi(); // 类型:UnpopulatedSchema[]
const populatedData = callApi(true); // 类型:PopulatedSchema[]
const mixedData = callApi(Math.random() > 0.5); // 类型:(UnpopulatedSchema | PopulatedSchema)[]

方案2:约束泛型为字面量类型

如果坚持使用条件类型,需要将泛型参数约束为true | false字面量(而非宽泛的boolean),让TypeScript能精准匹配条件分支:

type ObjectId = string;
type PopulatedProp = { id: ObjectId; name: string };

// 条件类型:仅接受true/false字面量
type Schema<T extends true | false> = T extends true 
  ? { prop1: PopulatedProp } 
  : { prop1: ObjectId };

// 泛型函数:约束T为true/false字面量
async function callApi<T extends true | false>(populate: T): Promise<Schema<T>[]> {
  const res = await fetch('/api/data');
  // 运行时无法保证类型,需添加类型断言
  return res.json() as Schema<T>[];
}

// 调用示例
const populatedData = callApi(true); // 类型:{ prop1: PopulatedProp }[]
const unpopulatedData = callApi(false); // 类型:{ prop1: ObjectId }[]

关键说明

  1. 函数重载的优势在于无需额外类型断言,类型推导更清晰,尤其适合对外暴露的API函数。
  2. 字面量泛型约束需要配合类型断言,因为TypeScript无法在编译时验证API返回的实际数据结构,断言是为了告诉编译器“运行时数据符合预期类型”。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:10:48