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

TypeScript中如何对unknown类型对象做类型收缩并访问属性

报错根本原因

你原写法报错是因为 TypeScript 的类型收缩规则限制,in 操作符目前无法给基础 object 类型追加属性标记。unknown 经过 typeof result === 'object' && result !== null 收缩后只能得到 object 类型,该类型默认没有任何已知属性,所以直接访问 movieName 就会触发类型错误。


方案1:自定义类型守卫(最推荐,类型安全最高)

写专用的类型判断函数,用类型谓词明确告知TS判断通过后的类型,逻辑可复用,不需要额外写后续断言:

// 定义类型守卫
function hasMovieName(obj: unknown): obj is { movieName: string } {
  return (
    typeof obj === 'object' &&
    obj !== null &&
    'movieName' in obj &&
    typeof (obj as Record<string, unknown>).movieName === 'string'
  )
}

const result: unknown = {
  movieName: "test",
};

if (hasMovieName(result)) {
  // 这里直接访问result.movieName不会报错,TS已经自动识别到类型
  console.log(result.movieName)
}

方案2:访问属性时临时断言

如果不想单独写守卫函数,可以在判断属性类型的位置临时做断言处理:

const result: unknown = {
  movieName: "test",
};

if (
  typeof result === "object" &&
  result !== null &&
  "movieName" in result &&
  typeof (result as Record<string, unknown>).movieName === "string"
) {
  // 后续使用前再做一次断言即可
  const validResult = result as { movieName: string }
  console.log(validResult.movieName)
}

方案3:提前收缩为Record<string, unknown>

如果可以接受先做一次断言把unknown转成松散的键值对类型,后续判断逻辑会更简洁:

const result: unknown = {
  movieName: "test",
};

// 先做基础校验+类型转换,不符合要求的分支提前退出
if (typeof result !== 'object' || result === null) {
  throw new Error('result格式错误')
}
const validResult = result as Record<string, unknown>

if (typeof validResult.movieName === 'string') {
  // 这里直接访问属性不会报错
  console.log(validResult.movieName)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:36:04