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

TypeScript条件自定义类型解构提示属性不存在如何解决

报错原因

FooOrBar属于联合类型,TypeScript对联合类型的属性访问有明确约束:仅当某个属性存在于联合类型的所有分支中时,才允许直接访问该属性。你的联合类型两个分支分别只包含foo、bar属性,不存在共有属性,因此直接解构两个属性会触发类型报错。

可行重构方案

方案1:用in操作符做类型收窄(最推荐,完全保留原逻辑)

in是TypeScript原生支持的类型收窄语法,可通过判断属性是否存在于对象上,自动把联合类型收窄到对应分支,不需要提前解构:

type FooOrBar = { foo: string } | { bar: string }
function doSomething(obj: FooOrBar) {
  if ('foo' in obj) {
    // 此分支内TS自动推导obj类型为{ foo: string },可安全访问obj.foo
    // 执行foo相关处理逻辑
    return
  }

  if ('bar' in obj) {
    // 此分支内TS自动推导obj类型为{ bar: string },可安全访问obj.bar
    // 执行bar相关处理逻辑
    return
  }

  throw new Error('入参必须包含foo或bar属性')
}

方案2:改造类型定义兼容解构写法

如果需要保留函数入口统一解构的写法,可以给联合类型的互斥属性补充可选的never类型标记,既允许同时访问两个属性,又能保留属性互斥的约束:

type FooOrBar = { foo: string; bar?: never } | { bar: string; foo?: never }
function doSomething(obj: FooOrBar) {
  const { foo, bar } = obj // 此处解构不会触发类型报错
  if (foo) {
    // 此分支内TS自动推导bar为undefined,不会出现同时传两个属性的情况
    // 执行foo相关处理逻辑
    return
  }

  if (bar) {
    // 此分支内TS自动推导foo为undefined
    // 执行bar相关处理逻辑
    return
  }

  throw new Error('入参必须包含foo或bar属性')
}

补充的bar?: never、foo?: never标记会让TS校验时禁止传入同时包含foo和bar属性的对象,完全符合你最初的互斥类型设计。

避坑提示

不要使用as any、// @ts-ignore这类方式强制跳过类型校验,这类写法会丢失TypeScript的类型保护能力,后续代码迭代时极易引入隐藏bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:01:05