新闻详情

新闻详情

首页 / 资讯中心 / 详情

使用 TypeGraphQL 定义 GraphQL Union 联合类型:从 createUnionType 到 resolveType 完整实战指南

发布时间:2026/9/28 2:22:46来源:尧图网络
使用 TypeGraphQL 定义 GraphQL Union 联合类型:从 createUnionType 到 resolveType 完整实战指南
后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载导读联合类型Union让 GraphQL API 可以在一个字段中返回多种不同类型的对象例如电影网站搜索接口同时返回Movie和Actor。本文以 TypeGraphQL 的createUnionType为核心讲解如何在类与装饰器驱动的 TypeScript 项目中定义 Union 类型、在 Resolver 中返回对应实例以及通过resolveType精确控制运行时类型判定并辅以仓库源码与测试用例佐证其底层实现。为什么需要 Union 类型GraphQL 规范允许字段的返回类型是「一组可能类型中的一种」。以电影网站的搜索功能为例用户输入关键词后数据库里既能命中电影Movie也能命中演员Actor。此时查询结果无法用一个固定的 Object Type 表达而需要返回Movie | Actor的集合。在 GraphQL 中这正对应Union Type的定义它本身不包含字段只是罗列一组成员 Object Type客户端必须用内联片段inline fragment按成员类型取字段。关于该类型的规范语义可参考 官方 GraphQL 文档。TypeGraphQL 提供了两个层面的支持装饰器ObjectType()用于定义成员类型类createUnionType工厂函数用于声明 Union 类型并注册到元数据存储中供buildSchema生成 Schema。定义 Union 的成员类型先用装饰器定义两个成员类型。以文档中的电影搜索示例为基础ObjectType() class Movie { Field() name: string; Field() rating: number; }import { Int } from type-graphql; ObjectType() class Actor { Field() name: string; Field(type Int) age: number; }两点需要注意每个成员类都必须带ObjectType()装饰器因为 Union 的成员必须是 Object Type数值字段如age需要用Field(type Int)显式指定标量类型否则反射会将其推断为默认的Float。用 createUnionType 创建联合类型import { createUnionType } from type-graphql; const SearchResultUnion createUnionType({ name: SearchResult, // GraphQL Schema 中的联合类型名称 types: () [Movie, Actor] as const, // 返回成员 Object Type 类元组的函数 });配置项说明配置项类型说明namestring必填生成的 GraphQL Union 类型名如SearchResulttypes() readonly ClassType[]必填惰性返回成员类元组的函数descriptionstring可选Schema 中该 Union 类型的描述resolveTypeTypeResolver可选自定义运行时类型判定函数见下文从源码看该工厂函数实现于 src/decorators/unions.ts它接收name、description、types与resolveType通过getMetadataStorage().collectUnionMetadata(...)将配置收集进元数据存储并返回一个唯一的symbol作为该 Union 类型的标识。声明类型UnionTypeConfigTClassTypes还通过UnionFromClasses定义在 src/helpers/utils.ts把类的元组推导为InstanceType联合实现编译期类型安全。为什么types必须是函数、且要用as consttypes被设计为函数而不是直接传数组是为了惰性求值、避免循环依赖Schema 生成时各类的元数据可能尚未收集完毕因此只有真正构建 Union 时才调用该函数取出类列表。源码 src/schema/schema-generator.ts 中typesThunk会在所有objectTypesInfo构建完成后被调用一次并把结果映射为GraphQLUnionType的成员类型。而as const语法把[Movie, Actor]标记为元组而不是普通数组这样UnionFromClasses能精确推导出Movie | Actor类型而不是Movie[] | Actor[]之类的宽泛类型从而让typeof SearchResultUnion具有准确的编译期类型。在 Resolver 中返回 Union 类型定义好 Union 后将其作为Query的返回类型注解传入。注意必须显式使用装饰器返回类型注解因为 TypeScript 的类型反射design:returntype无法识别这种「类型变量」这是 TypeScript 反射机制的固有限制。Resolver() class SearchResolver { Query(returns [SearchResultUnion]) async search(Arg(phrase) phrase: string): PromiseArraytypeof SearchResultUnion { const movies await Movies.findAll(phrase); const actors await Actors.findAll(phrase); return [...movies, ...actors]; } }这里的typeof SearchResultUnion在编译期等价于Movie | Actor既保证了返回值类型安全又与实际运行时返回的对象保持一致。若要返回 Union 列表则写成returns [SearchResultUnion]单个对象则为returns SearchResultUnion。从仓库示例 examples/enums-and-unions/search-result.union.ts 与 examples/enums-and-unions/resolver.ts 可以看到同款用法SearchResult联合Recipe | Cooksearch查询把食谱与厨师结果合并返回。Resolving Type运行时如何判定具体类型默认行为返回类实例当查询/变更的返回类型或字段类型是 Union 时Resolver 必须返回某个成员类的具体实例。默认情况下graphql-js需要借助「实例」来识别底层 GraphQL 类型如果直接返回普通 JS 对象plain object将无法判定类型。该默认行为对应源码 src/schema/schema-generator.ts 中的兜底逻辑未提供resolveType时默认函数会用instance instanceof ObjectClassType在成员类中查找匹配项再映射为对应类型名若找不到则抛出UnionResolveTypeError。自定义 resolveType返回普通对象更灵活的做法是在createUnionType配置中提供自己的resolveType实现。这样 Resolver 里可以返回普通 JS 对象由resolveType根据数据对象的形状来判定类型const SearchResultUnion createUnionType({ name: SearchResult, types: () [Movie, Actor] as const, // 根据数据形状检测返回的对象类型 resolveType: value { if (rating in value) { return Movie; // 返回带 ObjectType() 的成员类 } if (age in value) { return Actor; // 或直接返回类型在 Schema 中的名称字符串 } return undefined; }, });resolveType的返回值有两种合法形式成员类本身MovieTypeGraphQL 会将其映射到对应 GraphQL 类型Schema 中的类型名字符串Actor直接作为 GraphQL 类型名返回。配置类型定义见 src/decorators/types.ts 的ResolveTypeOptionsresolveType?: TypeResolverTSource, TContext即一个接收数据源、返回类型名的函数。测试用例 tests/functional/unions.ts 覆盖了这两种路径第 51-62 行UnionWithStringResolveType用字符串返回类型名第 65-76 行UnionWithClassResolveType返回成员类对应第 226、246 行的用例分别验证「用字符串/类正确识别返回对象类型」第 539 行起的用例还验证了resolveType返回undefined时 Schema 执行会报错Abstract type OneTwo must resolve to an Object type at runtime...提示需要提供resolveType或isTypeOf。客户端查询使用内联片段取字段定义并构建 Schema 后客户端查询时需要为每个成员类型使用... on TypeName内联片段query { search(phrase: Holmes) { ... on Actor { # Maybe Katie Holmes? name age } ... on Movie { # For sure Sherlock Holmes! name rating } } }由于 Union 类型本身没有字段客户端必须按成员类型分别取字段name在两个片段中分别对应各自类型的name字段。进阶用法与示例更多关于 Union以及 Enum的进阶用法可直接查看仓库中的完整可运行示例examples/enums-and-unions/index.ts 入口与 Schema 构建examples/enums-and-unions/search-result.union.ts Union 定义examples/enums-and-unions/resolver.ts 联合返回的查询实现examples/enums-and-unions/schema.graphql 生成的 Schema 文件可对照查看union SearchResult Cook | Recipe的最终形态。小结使用ObjectType()定义成员类型再用createUnionType({ name, types })创建 Uniontypes采用惰性函数 as const元组兼顾循环依赖规避与 TypeScript 类型推导Resolver 返回类型必须显式注解为 Union运行时要么返回成员类实例默认判定要么通过resolveType按数据形状返回类或类型名字符串客户端需用... on内联片段访问各成员字段。通过以上方式即可在 TypeGraphQL 项目中优雅地实现「一个查询返回多种类型」的灵活 API 设计。赞分享后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载相关推荐type-graphql Unions 联合类型完全指南从 createUnionType 定义到 resolveType 解析实战type graphql Unions 联合类型完全指南从 createUnionType 定义到 resolveType 解析实战 本指南以 type gr后端GraphQLAPI设计type-graphql 联合类型Union完整实战指南从 createUnionType 到类型解析type graphql 联合类型Union完整实战指南从 createUnionType 到类型解析 当 GraphQL API 需要让同一个查询字段返后端GraphQLAPI设计TypeGraphQL Unions 实战指南使用 createUnionType 定义与解析 GraphQL 联合类型TypeGraphQL Unions 实战指南使用 createUnionType 定义与解析 GraphQL 联合类型 本篇技术指南聚焦 TypeGraph后端GraphQLAPI设计上一篇4个实用技巧解决RevokeMsgPatcher微信防撤回补丁失效问题下一篇国家中小学智慧教育平台电子课本解析工具三步获取完整PDF教材的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

深度强化学习自动化股票交易策略:PPO/A2C/DDPG实战与回测 2026/9/28 3:07:16

深度强化学习自动化股票交易策略:PPO/A2C/DDPG实战与回测

简介:基于深度强化学习的自动化股票交易策略设计源码,面向金融AI研究者和量化交易初学者,提供从数据预处理、模型训练到回测评估的完整可运行项目,解决如何利用PPO、A2C、DDPG三类Actor-Critic算法自动学习股票交易决策的问题。压…

阅读更多 →
深入解析 @microsoft/fast-element 的 AttributeDefinition.name 属性:从装饰器到属性映射的完整链路 2026/9/28 3:07:16

深入解析 @microsoft/fast-element 的 AttributeDefinition.name 属性:从装饰器到属性映射的完整链路

前端UI组件 【免费下载链接】fast The adaptive interface system for modern web experiences. 项目地址: https://gitcode.com/gh_mirrors/fa/fast 点击查看 免费下载 导读 本文围绕 API 文档 AttributeDefinition.name property 展开,深入剖析 micr…

阅读更多 →
Kubernetes - Ingress 配置 HTTPS,实现安全的 HTTPS 访问 2026/9/28 3:07:16

Kubernetes - Ingress 配置 HTTPS,实现安全的 HTTPS 访问

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕Kubernetes这个话题展开,希望能为你带来一些…

阅读更多 →
北京网站策划服务新手入门:被黑挂马后的5步自救指南 2026/9/28 3:07:16

北京网站策划服务新手入门:被黑挂马后的5步自救指南

北京网站策划服务新手入门:被黑挂马后的5步自救指南 上周刚帮一个做跨境电商的朋友救火,他的网站突然弹出一堆赌博广告,后台代码全被改得面目全非。他急得满头汗,问我:“这网站还能要吗?是不是得重做?”我让他先别慌,把服务器日志和备份调出来看。其…

阅读更多 →
STM32引脚不够用?74HC595级联驱动6位数码管实战 2026/9/28 3:07:09

STM32引脚不够用?74HC595级联驱动6位数码管实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
5个坑位避开建建建设网站公司电话被黑免费工具指南 2026/9/28 3:07:02

5个坑位避开建建建设网站公司电话被黑免费工具指南

5个坑位避开建建建设网站公司电话被黑免费工具指南 备案流程一头雾水,后台密码泄露,网站瞬间变马?别慌,这不只是运气差,是安全底座没打牢。很多老板在找“建建建设网站公司电话”咨询时,只盯着价格和上线速度,忽略了最致命的隐患:…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉