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

GraphQL Nexus 含列表成员的Union类型实现咨询

问题解答

核心结论

你新增BookmarkSuccess对象类型包装书签数组的思路完全符合GraphQL规范,不需要做额外的特殊解析,只需要调整Union成员配置和查询返回结构即可。

问题原因

GraphQL 明确规定 Union 类型的成员只能是对象类型(Object Type),不支持直接将列表类型、标量类型作为Union成员,因此你最初期望的[Bookmark]! | NotAllowedError | NotFoundError | UnknownError写法本身不符合类型系统规则,必须通过对象类型包装数组字段。

具体实现步骤

  1. 调整Union类型定义,将原成员中的Bookmark替换为BookmarkSuccess,同时补充resolveType逻辑,让GraphQL能识别返回结果对应的成员类型:
    const BookmarkResult = unionType({
      name: 'BookmarkResult',
      definition(t) {
        t.members('BookmarkSuccess', 'NotAllowedError', 'NotFoundError', 'UnknownError')
      },
      resolveType: (res) => {
        if ('bookmarks' in res) return 'BookmarkSuccess'
        if (res.errorType === 'NOT_ALLOWED') return 'NotAllowedError'
        if (res.errorType === 'NOT_FOUND') return 'NotFoundError'
        return 'UnknownError'
      }
    })
    
  2. 完成BookmarkSuccess类型定义,bookmarks字段不需要手写resolve,GraphQL默认解析器会自动读取父对象上的同名属性:
    const BookmarkSuccess = objectType({
      name: 'BookmarkSuccess',
      definition(t) {
        t.nonNull.list.nonNull.field('bookmarks', {
          type: 'Bookmark'
          // 无需自定义resolve
        })
      }
    })
    
  3. 调整查询字段的resolve逻辑,成功分支将书签数组包装为带bookmarks属性的普通对象即可,错误分支逻辑无需改动:
    const BookmarkQuery = queryField('links', {
      type: 'BookmarkResult',
      resolve: async () => await pipe(
        getAllBookmarks(),
        foldW(
          // 错误分支保持原有逻辑,直接返回错误对象
          (err) => err,
          // 成功分支包装为BookmarkSuccess对应的结构
          (bookmarks) => ({ bookmarks })
        )
      )()
    })
    

注意事项

  • 如果你原来的代码用of方法构造返回值,只需要把成功分支的of(bookmarks)改为of({ bookmarks })即可,其余逻辑无需调整。
  • 必须为Union配置resolveType,或在每个成员类型上配置isTypeOf判断逻辑,否则GraphQL运行时无法识别返回结果对应的Union成员,会抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:16:00