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

TypeScript提示children属性不存在,但类型定义中已包含该属性

解决Sanity查询中TypeScript提示children属性不存在的问题

问题原因

你的POST_QUERYResult类型里,body是可选数组,且数组元素为联合类型:要么是带children的block类型,要么是不带children的image类型。同时body本身、children都是可选属性,TypeScript无法确定你访问的元素一定是block类型,因此触发类型错误。

解决方法

1. 使用类型守卫(类型安全推荐方案)

提取block类型并编写类型守卫函数,让TypeScript明确当前元素的类型:

// 单独提取block类型,提升复用性
type PostBlock = Extract<NonNullable<POST_QUERYResult["body"]>[number], { _type: "block" }>;

// 类型守卫函数,判断元素是否为block类型
function isPostBlock(item: NonNullable<POST_QUERYResult["body"]>[number]): item is PostBlock {
  return item._type === "block";
}

// 使用示例
if (result?.body) {
  for (const item of result.body) {
    if (isPostBlock(item)) {
      // 此处TypeScript会确认item为block类型,可安全访问children
      console.log(item.children);
    }
  }
}

2. 可选链+空值合并(快速规避报错)

通过可选链?.处理多层可选属性,配合空值合并??设置默认值,快速消除类型报错:

// 访问首个元素的children
const firstChildren = result?.body?.[0]?.children ?? [];

// 遍历处理(注意:类型断言存在运行时风险,仅临时场景使用)
result?.body?.forEach(item => {
  const children = (item as PostBlock).children ?? [];
});

3. 优化GROQ查询(从源头缩小类型范围)

修改查询语句,过滤掉body中的image类型元素,让返回数据的类型更精准:

// 修改后的查询:仅保留body里的block类型元素
export const POST_QUERY = defineQuery(`
*[_type == "post" && slug.current == $slug][0] {
  ...,
  body: body[_type == "block"]
}
`);

此时POST_QUERYResult的body数组只会包含block类型,访问children时不会再触发类型错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:00:15