新闻详情

新闻详情

首页 / 资讯中心 / 详情

TypeGraphQL 标量类型完全指南:内置别名、Date 标量与自定义 GraphQLScalarType

发布时间:2026/9/27 6:27:53来源:尧图网络
TypeGraphQL 标量类型完全指南:内置别名、Date 标量与自定义 GraphQLScalarType
后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载导读在 TypeGraphQL 中标量Scalar是连接 TypeScript 类型与 GraphQL 内置基础类型的关键一环。本指南基于 0.16.0 版本文档系统讲解三类标量处理方案用Int/Float/ID别名简化字段声明、内置 Date 标量的两种序列化格式以及如何创建并接入自定义GraphQLScalarType如 MongoDB 的 ObjectId。读完本文你将掌握字段类型自动推断的边界、通过buildSchema选项统一控制标量映射的方法并能用scalarsMap让自定义标量零注解接入 schema。一、基础标量别名用Int、Float、ID少敲键盘1.1 三个官方别名TypeGraphQL 为 3 个基础标量提供了等价别名定义在 src/scalars/aliases.ts 中本质就是graphql包标量对象的直接引用Int→GraphQLIntFloat→GraphQLFloatID→GraphQLID因此你可以用更短的写法在字段装饰器中声明类型import { ID, Float, Int } from type-graphql; ObjectType() class MysteryObject { Field(type ID) readonly id: string; Field(type Int) notificationsCount: number; Field(type Float) probability: number; }1.2 自动推断的边界哪些可以不写type 并非所有字段都必须显式写类型。TypeGraphQL 在 schema 生成阶段会执行一套标量转换逻辑核心实现在 src/helpers/types.ts 的convertTypeIfScalar函数中src/helpers/types.ts#L28-L49Number自动映射为GraphQLFloatString自动映射为GraphQLStringBoolean自动映射为GraphQLBooleanDate自动映射为GraphQLISODateTime详见下文所以上面示例中的probability字段可以省略type Float直接写成ObjectType() class MysteryObject { Field() probability: number; }同理GraphQLString与GraphQLBoolean不需要别名能自动反射时直接留空即可ObjectType() class User { Field() name: string; Field() isOld: boolean; }这一行为在测试 tests/functional/scalars.ts#L152-L178 中有明确验证当属性类型为number时内省结果introspection中字段类型是Float属性类型为string时字段类型是String。1.3 何时必须显式声明 String / BooleanTypeScript 的emitDecoratorMetadata反射机制只能正确记录属性类型而方法的返回类型在反射时会退化为Object。例如下面这个带 getter 的字段TS 反射出的类型是ObjectTypeGraphQL 无法推断它应映射到String因此必须显式用 JS 构造函数String声明ObjectType() class SampleObject { Field(type String, { nullable: true }) get optionalInfo(): string | undefined { // TS reflected type is Object :( if (Math.random() 0.5) { return Gotcha!; } } }遇到这类反射信息缺失的情况就用 JS 构造函数String、Boolean、Number作为显式类型兜底测试 tests/functional/scalars.ts#L58-L65 中explicitStringField、explicitBooleanField正是这种用法。二、内置 Date 标量ISO 格式与时间戳格式2.1 两种格式与对应导出TypeGraphQL 为Date类型内置了两种标量实现时间戳格式timestamp序列化为毫秒级数字如1518037458374ISO 格式isoDate序列化为 ISO 8601 字符串如2018-02-07T21:04:39.573Z在 0.16.0 版本中它们从type-graphql包导出为GraphQLISODateScalar与GraphQLTimestampScalar。需要说明的是在后续版本即当前仓库版本中这两个标量的命名已演进为GraphQLISODateTime与GraphQLTimestamp且实现来自graphql-scalarsnpm 包可在 src/scalars/index.ts 中看到export { GraphQLTimestamp, GraphQLDateTimeISO as GraphQLISODateTime } from graphql-scalars;2.2 默认格式与全局切换默认情况下 TypeGraphQL 使用ISO 日期格式。0.16.0 文档中通过buildSchema的dateScalarMode选项切换格式import { buildSchema } from type-graphql; const schema await buildSchema({ resolvers, dateScalarMode: timestamp, // timestamp or isoDate });而在当前仓库版本中这一开关已统一收编进更通用的scalarsMap机制BuildContextOptions中已不存在dateScalarMode见 src/schema/build-context.ts#L18-L42用法等价于import { buildSchema, GraphQLTimestamp } from type-graphql; const schema await buildSchema({ resolvers, scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }], });两种写法的核心效果一致让Date类型统一按指定格式序列化。配置之后字段声明无需显式标注类型ObjectType() class User { Field() registrationDate: Date; }默认 ISO 行为与scalarsMap覆盖行为在 tests/functional/scalars.ts#L268-L298 中均有测试佐证默认生成的字段类型名为DateTimeISO传入scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }]后字段类型名为Timestamp。此外测试还证明scalarsMap可以完全覆盖默认 Date 映射如 tests/functional/scalars.ts#L327-L352 用自定义标量替换 Date 映射。2.3 ts-node 使用提醒如果你用ts-node运行 TypeGraphQL 代码必须加上--type-check标志执行——这是为了规避 ts-node 历史上存在的 Date 反射design:type 元数据问题否则Date字段的类型可能无法被正确反射出来。三、自定义标量接入 ObjectId 等第三方类型3.1 第一步创建GraphQLScalarType实例自定义标量的第一步是创建一个GraphQLScalarType实例可以自己写也可以从第三方 npm 库导入。以 MongoDB 的ObjectId为例import { GraphQLScalarType, Kind } from graphql; import { ObjectId } from mongodb; export const ObjectIdScalar new GraphQLScalarType({ name: ObjectId, description: Mongo object id scalar type, parseValue(value: string) { return new ObjectId(value); // value from the client input variables }, serialize(value: ObjectId) { return value.toHexString(); // value sent to the client }, parseLiteral(ast) { if (ast.kind Kind.STRING) { return new ObjectId(ast.value); // value from the client query } return null; }, });三个回调各自负责一段数据旅程serialize服务端数据 → 客户端响应序列化例如把ObjectId转成十六进制字符串parseValue客户端输入变量variables→ 服务端运行时对象parseLiteral客户端查询中的字面量AST 节点→ 服务端运行时对象通常需要按ast.kind判断字面量类型仓库测试辅助文件 tests/helpers/customScalar.ts 也展示了同样结构的极简自定义标量其serialize返回字符串TypeGraphQL serialize、parseLiteral返回TypeGraphQL parseLiteral用于验证整个读写链路。3.2 第二步在字段装饰器中显式使用创建好标量后在Field中显式指定即可// import the earlier created const import { ObjectIdScalar } from ../my-scalars/ObjectId; ObjectType() class User { Field(type ObjectIdScalar) // and explicitly use it readonly id: ObjectId; Field() name: string; Field() isOld: boolean; }测试 tests/functional/scalars.ts#L216-L244 完整验证了自定义标量的行为查询returnScalar时serialize被调用查询参数argScalar(scalar: test)时parseLiteral被调用证明自定义标量在返回值和入参两个方向上都正常工作。3.3 第三步可选用scalarsMap实现零注解自动映射如果不想在每个字段上都写type ObjectIdScalar可以声明反射属性类型 ↔ 标量的关联关系让 TypeGraphQL 自动匹配ObjectType() class User { Field() // magic goes here - no type annotation for custom scalar readonly id: ObjectId; }只需在buildSchema中注册映射表import { ObjectId } from mongodb; import { ObjectIdScalar } from ../my-scalars/ObjectId; import { buildSchema } from type-graphql; const schema await buildSchema({ resolvers, scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }], });从源码看scalarsMap的每个条目是{ type: Function; scalar: GraphQLScalarType }结构src/schema/build-context.ts#L11-L14构建 schema 时被存入BuildContext.scalarsMaps。convertTypeIfScalar在把 TS 类型转为 GraphQL 类型时会优先查找该映射表命中即返回对应的自定义标量其次才走String/Boolean/Number/Date的内置映射src/helpers/types.ts#L28-L49。也就是说scalarsMap的优先级高于内置映射甚至可以覆盖Date的默认映射——这正是 2.2 节中scalarsMap取代dateScalarMode能成立的根本原因。3.4 自动映射的硬性限制这种零注解方式能否生效取决于 TypeScript 反射机制能否处理你的属性类型。属性类型必须是class如ObjectId不能是枚举enum、联合类型union或接口interface——因为design:type元数据只对类类型有可靠的反射结果。若反射拿不到类型TypeGraphQL 会因缺少显式类型而无法推断findType中会抛出NoExplicitTypeError见 src/helpers/findType.ts#L64-L66此时仍需回到 3.2 节的显式声明方式。四、小结与选型建议围绕标量类型可以按以下规则决策场景推荐做法Int/Float/ID字段使用Int、Float、ID别名或依赖Number自动映射为Floatstring/boolean普通属性直接留空Field()自动反射getter 方法、反射退化为Object的字段显式写type String/Boolean/NumberDate字段默认 ISO无需声明需要时间戳格式时用scalarsMap映射到GraphQLTimestampMongoDB ObjectId 等第三方类型创建GraphQLScalarType后显式声明或用scalarsMap全局注册实现自动映射涉及的具体源码与测试位置别名定义 src/scalars/aliases.ts、标量导出 src/scalars/index.ts、类型转换核心 src/helpers/types.ts#L28-L49、构建上下文 src/schema/build-context.ts#L18-L42、完整功能测试 tests/functional/scalars.ts。掌握这些机制后无论是基础字段还是 ObjectId、BigInt 等特殊类型都能在 TypeGraphQL 中自然、类型安全地融入 GraphQL schema。赞分享后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载相关推荐Windows 11终极优化指南用Win11Debloat重获系统控制权Windows 11终极优化指南用Win11Debloat重获系统控制权 你的Windows 11电脑是否变得越来越臃肿开机时间越来越长后台进程悄悄吃后端GraphQLAPI设计TypeGraphQL 标量Scalar类型完全指南内置别名、Date 标量与自定义标量version-0.17.1TypeGraphQL 标量Scalar类型完全指南内置别名、Date 标量与自定义标量version 0.17.1 本篇指南以 TypeGraphQ后端GraphQLAPI设计TypeGraphQL 标量类型Scalars完全指南内置别名、自动推断与自定义 Scalar 实战TypeGraphQL 标量类型Scalars完全指南内置别名、自动推断与自定义 Scalar 实战 导读 本文围绕 TypeGraphQL 的标量Sc后端GraphQLAPI设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

3个实战案例揭秘小红书sem是什么意思 2026/9/27 7:15:21

3个实战案例揭秘小红书sem是什么意思

3个实战案例揭秘小红书sem是什么意思 网站做好了没人访问,是不是你的常态?很多老板花大价钱让外包公司搭了个站,上线一个月,后台流量个位数,连自己都懒得点开看。别急,这往往不是网站做得丑,而是你没搞懂流量从哪来。今天不聊虚的,直接拆解三个…

阅读更多 →
Zeek 是什么:被动式开源网络流量分析框架的定位、能力与架构解析 2026/9/27 7:15:21

Zeek 是什么:被动式开源网络流量分析框架的定位、能力与架构解析

网络安全网络IDS 【免费下载链接】zeek Zeek is a powerful network analysis framework that is much different from the typical IDS you may know. 项目地址: https://gitcode.com/gh_mirrors/ze/zeek 点击查看 免费下载 导读:本文以 Zeek 官方手册…

阅读更多 →
数据库误删数据,事前如何识别和拦截高危 SQL? 2026/9/27 7:15:14

数据库误删数据,事前如何识别和拦截高危 SQL?

生产数据库发生误删、误更新后,团队通常会立刻检查备份、Binlog、归档日志和恢复方案。这些措施很重要,但它们解决的主要是“事故发生后如何恢复”,并不能替代执行前的风险控制。 对生产环境而言,更理想的目标不是等数据被删后再恢…

阅读更多 →
ChatGPT Shortcut 浏览器扩展完整指南:在 ChatGPT / Gemini / Claude / Doubao 侧边栏一键调用 AiShort 提示词库 2026/9/27 7:15:08

ChatGPT Shortcut 浏览器扩展完整指南:在 ChatGPT / Gemini / Claude / Doubao 侧边栏一键调用 AiShort 提示词库

AI 应用提示工程人工智能前端 【免费下载链接】ChatGPT-Shortcut Stop writing prompts from scratch — a searchable prompt library for ChatGPT, Claude, Gemini and Cursor Русский 한국어 العربية हिन्दी ไทย | 别再从头写提示词&…

阅读更多 →
陕西网站备案查询避坑指南:新手做站必看3大注意事项 2026/9/27 7:15:07

陕西网站备案查询避坑指南:新手做站必看3大注意事项

陕西网站备案查询避坑指南:新手做站必看3大注意事项 自己不会代码想做网站,是不是觉得只要买个域名、搞台服务器就能开张?别天真了。在陕西,甚至在全国, 网站ICP备案 才是你网站能不能合法上线的“生死线”。很多新手因为不懂 陕西网站备案查询…

阅读更多 →
网站开发后台编辑系统选错?2026最新避坑指南 2026/9/27 7:14:48

网站开发后台编辑系统选错?2026最新避坑指南

网站开发后台编辑系统选错?2026最新避坑指南 网站做好了没人访问,多半是后台编辑系统拖了后腿。很多新手刚入行,盯着前端UI看半天,却忽略了后台编辑的易用性,导致运营人员改个标题都要找开发,效率低到让人崩溃。2026最新的建站趋势里,后台不…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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