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

TypeScript中如何实现Result类型的自动解包与类型收窄,无需额外判断error属性

解决Result联合类型的类型解包问题

你遇到的核心问题是TypeScript无法自动推断出unwrapResult函数抛出错误后,返回的必然是联合类型中无error的成功成员。我们可以通过条件类型配合类型断言,让函数返回类型精确匹配成功结果,这样调用后就能直接访问response属性,无需额外判断。

解决方案代码

首先定义一个辅助类型,用来提取联合类型中error为undefined的成功分支:

type SuccessResult<T> = T extends { error: undefined } ? T : never;

接着修改unwrapResult函数,让它返回这个精确的成功类型:

type Result = {error:true,response: undefined} | {error:undefined, response:{nick:string}}

function unwrapResult<T extends { error: any }>(result: T): SuccessResult<T> { 
  if(result.error){ 
    throw result.error 
  } 
  // 类型断言是安全的:运行时已通过if排除了error存在的情况
  return result as SuccessResult<T> 
}

function test():Result { 
  return {error:undefined,response:{nick:'iki'}} 
}

// data的类型被正确推断为{error:undefined, response:{nick:string}}
const data = unwrapResult(test())
// 可直接访问,无需可选链或额外判断
console.log(data.response.nick) // 类型为string,无undefined提示

原函数失效的原因

你的原函数返回泛型参数T,而T对应Result联合类型。虽然运行时我们抛出错误只返回成功结果,但TypeScript类型系统无法自动从联合类型中排除带error的分支——它只能识别函数返回的是T(即原联合类型),因此response仍会被标记为undefined | {nick:string}。

通过SuccessResult<T>条件类型,我们明确告知TypeScript:仅当传入的T包含error: undefined时返回该类型,否则返回never(错误分支已被抛出,不会走到return)。配合类型断言让TypeScript认可运行时判断,就能得到精确的类型。

更通用的简化写法(直接返回response数据)

如果只关心成功后的response数据,还可以进一步简化函数,直接返回response的类型:

type UnwrapSuccess<T> = T extends { error: any; response?: never } 
  ? never 
  : T extends { error?: never; response: infer R } 
  ? R 
  : never;

function unwrapResult<T>(result: T): UnwrapSuccess<T> {
  if ('error' in result && result.error) {
    throw result.error;
  }
  return (result as any).response;
}

// 使用示例
const data = unwrapResult(test())
// data的类型直接是{nick:string},无需处理error属性
console.log(data.nick)

内容的提问来源于stack exchange,提问作者Ivan V.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:27:47