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

TypeScript中能否将参数param的类型从T0 | T1重新分配为T0类型?

TypeScript联合类型窄化:通过hasOwnProperty判断后如何将类型重新分配为T0?

先看你给出的代码示例:

type T0 = { a: string; b: string }
type T1 = Omit<T0, 'b'>
function func({ param }: { param: T0 | T1 }) { 
  if (param.hasOwnProperty('b')) { 
    /* reassign type */ 
  } 
  return param.b // 这里会触发TS类型错误,因为T1没有b属性
}

当然有可行的方法!不过要说明:原生的hasOwnProperty()调用并不会让TypeScript自动把param的类型从T0 | T1窄化为T0——TS对这个方法的类型推导没有做特殊优化。下面给你两个实用的解决方案:

方案1:用in操作符实现自动类型窄化

这是最直接的方法,TS原生支持用in操作符根据属性存在性来窄化联合类型,完全不需要额外代码:

type T0 = { a: string; b: string }
type T1 = Omit<T0, 'b'>
function func({ param }: { param: T0 | T1 }) { 
  if ('b' in param) { 
    // 到这里TS已经自动把param推断为T0类型了
    console.log(param.b) // 类型安全,不会报错
    return param.b
  }
  // 处理T1的情况,避免返回值类型错误
  return 'b属性不存在'
}

方案2:自定义类型守卫函数(如果一定要用hasOwnProperty)

如果你坚持要使用hasOwnProperty来判断,可以写一个自定义类型守卫函数,手动告诉TS如何根据判断结果推导类型:

type T0 = { a: string; b: string }
type T1 = Omit<T0, 'b'>

// 自定义类型守卫:返回true时,obj会被TS推断为T0类型
function isT0(obj: T0 | T1): obj is T0 {
  return obj.hasOwnProperty('b')
}

function func({ param }: { param: T0 | T1 }) { 
  if (isT0(param)) { 
    // 这里param已经被窄化为T0类型
    return param.b 
  }
  // 必须处理T1的分支,保证类型完整性
  return '默认值'
}

补充:为什么hasOwnProperty默认不行?

因为hasOwnProperty的返回值只是普通的boolean类型,TS无法从这个布尔值直接关联到对象的属性存在性与类型的对应关系。而in是TS专门做了类型优化的语法,它能直接建立“属性存在”和“类型匹配”的关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:22:25