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
相关产品推荐
相关产品推荐

