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

Typescript类型收窄无法正确解析对象属性类型问题

问题产生原因

这个报错是TypeScript控制流分析的类型收缩(Narrowing)机制的限制导致的:

  • 你在if分支中仅对obj.prop这个单独属性做了非空、类型校验,TypeScript只会收缩obj.prop这个属性自身的类型,不会自动把整个obj对象的类型从Wide收窄为Narrow。
  • 当你使用扩展运算符...obj构造新对象传入Foo构造函数时,TypeScript仍然会按照Wide类型来解析obj,认为它的prop属性是string | undefined类型,不符合Narrow接口的要求,因此抛出类型错误。

额外说明:你写的if校验存在冗余,obj.prop && typeof obj.prop === 'string'已经可以完全排除undefined的情况,不需要额外判断obj.prop !== undefined。

解决方案

提供几种常用的修复方案,可根据场景选择:

方案1:直接传入校验后的属性(最推荐)

直接传递已经完成类型校验的prop属性,不要扩展整个obj对象,TypeScript可以正确识别obj.prop已经被收缩为string类型:

array.forEach((obj: Wide) => {
  if (typeof obj.prop === 'string') {
    console.log(new Foo({ prop: obj.prop }))
  }
})

方案2:使用类型守卫收窄整个对象类型

如果需要频繁判断Wide类型是否符合Narrow的要求,可以编写自定义类型守卫,触发TypeScript对整个对象的类型收窄:

// 自定义类型守卫
function isNarrow(obj: Wide): obj is Narrow {
  return typeof obj.prop === 'string'
}

array.forEach((obj: Wide) => {
  if (isNarrow(obj)) {
    console.log(new Foo({ ...obj })) // 此时obj类型已经被收窄为Narrow,不会报错
  }
})

方案3:使用类型断言跳过校验

如果你100%确定当前场景下obj的prop属性已经是string类型,可以用类型断言直接告诉TypeScript按照Narrow类型处理:

array.forEach((obj: Wide) => {
  if (typeof obj.prop === 'string') {
    console.log(new Foo({ ...obj } as Narrow))
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:27:03