Gatsby+WordPress+TypeScript项目WpContentNode[]不可分配给WpPage[]问题
问题根因
wpChildren.nodes的基础返回类型为WpContentNode[],WpContentNode是WpPage、WpPost等所有WordPress内容类型的共用上层接口。即使你在查询中添加了... on WpPage内联片段,graphql-codegen默认也不会自动将整个数组的类型收窄为WpPage[],只会给数组元素增加WpPage对应的字段定义,因此出现类型不匹配报错。
解决方案(均符合严格类型规范,无需使用any)
方案1:类型谓词校验(最推荐,带运行时安全保障)
通过类型谓词函数过滤数组,TS会自动将通过校验的数组收窄为WpPage[]类型,同时可以过滤掉不符合预期的非页面类型节点,避免脏数据影响:
// 类型谓词函数,判断单个节点是否为WpPage类型 function isWpPage(node: WpContentNode): node is WpPage { // GraphQL返回的所有内容节点都会自动携带__typename字段,无需手动在查询中声明 return node.__typename === 'WpPage'; } // 调用filter过滤得到类型正确的数组 const pages: WpPage[] = (page?.wpChildren?.nodes || []).filter(isWpPage);
方案2:调整graphql-codegen配置自动收窄类型
如果你确定该查询返回的子节点只会是WpPage类型,可以修改codegen配置,让其自动识别内联片段完成类型收窄:
找到项目中的codegen配置文件(通常为codegen.yml或codegen.ts),在typescript-operations插件配置中添加如下参数:
plugins: - typescript - typescript-operations: preResolveTypes: true mergeFragmentTypes: true
修改配置后重新执行类型生成命令,codegen会自动将仅包含... on WpPage片段的nodes数组推导为WpPage[]类型。
方案3:类型断言(适合确定数据结构的场景)
如果你业务上100%确认该父页面的所有子节点都只会是WpPage类型,没有其他内容类型,可以直接使用类型断言,比any更安全且符合严格类型要求:
const pages: WpPage[] = (page?.wpChildren?.nodes || []) as WpPage[];
注意该方案没有运行时校验,仅在你完全确定返回数据结构时使用。
内容的提问来源于stack exchange,提问作者Mission Mike
相关产品推荐
相关产品推荐

