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

如何基于入参选项对象中的布尔标识收窄TypeScript函数返回值类型?

让TypeScript根据布尔参数推断函数返回类型的解决方案

你的问题核心在于TypeScript无法将options.raw的具体布尔值与函数返回类型建立关联,导致返回类型被推断为Promise<RawResponse | string[]>,进而调用map时出现类型错误。以下两种方案可以解决这个问题:

方案一:泛型结合条件类型

通过给Option类型添加泛型参数,将raw的具体值与返回类型绑定:

type Option<T extends boolean = boolean> = {
  param: string
  raw?: T
  otherParam?: string;
}

type RawResponse = {
  message: string
  data: string[]
}

function fakeFetch() {
  return Promise.resolve({ message: "Hello", data: ["test1", "test2"] } as RawResponse)
}

async function foo<T extends boolean = boolean>(options: Option<T>): Promise<T extends true ? RawResponse : string[]> {
  const response = await fakeFetch()

  if (options.raw) {
    return response as T extends true ? RawResponse : string[]
  }

  return response.data as T extends true ? RawResponse : string[]
}

调用示例

// raw: false 时,返回类型自动推断为 Promise<string[]>,可正常调用map
foo({param: "test", raw: false}).then(results => {
  results.map(result => console.log(result))
});

// raw: true 时,返回类型自动推断为 Promise<RawResponse>
foo({param: "test", raw: true}).then(results => {
  console.log(results.message)
});

// 不传入raw时,返回类型为 Promise<RawResponse | string[]>,需手动做类型守卫
foo({param: "test"}).then(results => {
  if ('message' in results) {
    console.log(results.message)
  } else {
    results.map(r => console.log(r))
  }
});

方案二:函数重载

通过定义多个函数重载签名,明确不同raw值对应的返回类型:

type Option = {
  param: string
  raw?: boolean
  otherParam?: string;
}

type RawResponse = {
  message: string
  data: string[]
}

function fakeFetch() {
  return Promise.resolve({ message: "Hello", data: ["test1", "test2"] } as RawResponse)
}

// 重载签名:raw为true时返回RawResponse的Promise
function foo(options: Option & { raw: true }): Promise<RawResponse>;
// 重载签名:raw为false时返回string[]的Promise
function foo(options: Option & { raw: false }): Promise<string[]>;
// 重载签名:不传入raw时返回联合类型的Promise
function foo(options: Option): Promise<RawResponse | string[]>;

// 函数实现
async function foo(options: Option) {
  const response = await fakeFetch()

  if (options.raw) {
    return response
  }

  return response.data
}

调用示例

foo({param: "test", raw: false}).then(results => {
  results.map(result => console.log(result)) // 类型推断正确,无报错
});

foo({param: "test", raw: true}).then(results => {
  console.log(results.message) // 正确识别为RawResponse类型
});

原代码问题说明

原代码中Option的raw是可选布尔类型,TypeScript无法将调用时传入的raw具体值(true/false)与函数返回类型做关联,因此返回类型只能推断为Promise<RawResponse | string[]>,调用map时因为RawResponse没有该方法,所以触发类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:00:53