ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TypeSpec GraphQL Emitter 数据类型详解:ID 标量与 SchemaOptions 配置

TypeSpec GraphQL Emitter 数据类型详解:ID 标量与 SchemaOptions 配置 TypeSpec GraphQL Emitter 数据类型详解ID 标量与 SchemaOptions 配置【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec本文围绕typespec/graphql导出的数据类型参考文档展开完整解析TypeSpec.GraphQL.ID标量与TypeSpec.GraphQL.Schema.SchemaOptions两个核心类型并结合开源仓库中的标准库定义lib/*.tsp、标量映射表、mutation 引擎与测试用例说明它们在 TypeSpec → GraphQL Schema 发射流程中的真实行为。读完后你将掌握如何在 TypeSpec 中声明 GraphQL 标识符类型、如何为多 Schema 场景命名输出文件以及自定义标量是如何被解析和重写的。TypeSpec.GraphQL.IDGraphQL 原生 ID 标量类型定义与语义在 TypeSpec GraphQL emitter 库中ID是一个扩展自string的标准库标量用于表示 GraphQL 规范中的 ID 标量——一种以字符串形式序列化的唯一标识符scalar TypeSpec.GraphQL.ID其标准库源码位于 scalars.tsp定义如下namespace TypeSpec.GraphQL; /** * Represents a GraphQL ID scalar — a unique identifier serialized as a string. * * see https://spec.graphql.org/September2025/#sec-ID */ scalar ID extends string;文档给出的典型用法是为模型的主键字段声明GraphQL.ID类型model User { id: GraphQL.ID; name: string; }源码中的识别逻辑为什么ID会被直接映射普通 TypeSpec 内置标量如string、int32在发射时会被解析为 GraphQL 内置类型而TypeSpec.GraphQL.ID有专门的识别路径。在 mutation 引擎的标量重写逻辑 scalar.ts 中isGraphQLIdScalar函数会沿着baseScalar继承链向上查找只要链路中出现TypeSpec命名空间下GraphQL命名空间里的ID标量就判定为目标function isGraphQLIdScalar(scalar: Scalar): boolean { let current: Scalar | undefined scalar; while (current) { if ( current.name ID current.namespace?.name GraphQL current.namespace?.namespace?.name TypeSpec ) { return true; } current current.baseScalar; } return false; }这意味着不仅GraphQL.ID本身任何scalar MyId extends GraphQL.ID形式的派生标量在GraphQLScalarMutation.mutate()中都会被改写为 GraphQL 内置的ID类型并清空其baseScalar见 scalar.ts。这与标量映射表 scalar-mappings.ts 中的条目相互印证// GraphQL library scalar (TypeSpec.GraphQL.ID) ID: { default: { graphqlType: ID }, },值得注意的是映射表中ID没有customScalarName字段因为ID是 GraphQL 规范的五大内置标量String、Int、Float、Boolean、ID之一不需要在输出中声明为自定义标量。标量映射表全景理解ID在体系中的位置ID所在的映射表SCALAR_MAPPINGSscalar-mappings.ts覆盖了 TypeSpec 标准库全部内置标量。每条映射包含三个可选字段字段含义graphqlType字段引用时使用的 GraphQL 类型名如String、Int、IDcustomScalarName需要显式声明自定义标量时使用的名称如Long、BigDecimalspecificationUrl用于输出specifiedBy指令的规范 URLID只配置了graphqlType: ID与string→String、int32→Int、float32/float64→Float等直接映射同属一类而int64→StringLong、decimal→StringBigDecimal等则带自定义标量与规范 URL。测试用例 scalar-mappings.test.ts 对上述映射做了逐项断言其中对ID的断言为describe(GraphQL library scalar, () { it(maps ID to ID, () { expect(resolveScalarToGraphQL(ID)).toBe(ID); }); });对于表外标量resolveScalarToGraphQL会原样返回标量名scalar-mappings.ts这正是用户自定义标量user-defined scalars能被保留到 GraphQL 输出的基础。TypeSpec.GraphQL.Schema.SchemaOptionsSchema 配置选项类型定义与属性SchemaOptions是配置 GraphQL schema 的选项模型定义在标准库文件 schema.tspmodel TypeSpec.GraphQL.Schema.SchemaOptionsNameTypeDescriptionname?stringThe name of the GraphQL schema. Used in the output filename when emitting multiple schemas (e.g.,{name}.graphql). Defaults toschema.当前版本中SchemaOptions只有一个可选属性name它在一次编译输出多个 schema 时决定输出文件名如MyAPI.graphql未指定时默认为schema。与schema装饰器的协作SchemaOptions是schema装饰器的参数类型。同一文件中声明了该装饰器schema.tsp/** * Mark this namespace as describing a GraphQL schema and configure schema properties. * All types and operations within the namespace will be emitted to a single GraphQL schema file. * * example * * typespec * schema(#{ name: MyAPI }) * namespace MyAPI { * model User { id: string; name: string; } * query op getUser(id: string): User; * } * // Emits: MyAPI.graphql * * * param options Options for the schema, such as its name. */ extern dec schema(target: Namespace, options?: valueof Schema.SchemaOptions);从文档示例可以看出完整工作流用schema装饰一个命名空间命名空间内的所有类型与操作会被发射到同一个.graphql文件通过#{ name: MyAPI }传入SchemaOptions输出即为MyAPI.graphql。底层实现选项如何落到 Program 状态上装饰器实现位于 schema.ts。$schema的实现schema.ts非常直接export const $schema: SchemaDecorator (context, target, options) { validateDecoratorUniqueOnNode(context, target, $schema); addSchema(context.program, target, options); };几个关键行为可以从源码确认幂等合并addSchemaschema.ts会读取已有条目并做{ ...existing, ...details, type: namespace }合并因此重复处理同一命名空间时不会丢失此前的name设置唯一性校验validateDecoratorUniqueOnNode保证同一命名空间上不会叠加多个schema装饰器查询 APIisSchema(program, namespace)判断某命名空间是否为 schema 命名空间listSchemas(program)返回整个编译单元中所有 schemaschema.ts。这些 API 被 emitter 在输出阶段用来枚举 schema 并按name生成{name}.graphql文件名。标量声明的发射形态ScalarType 组件ID之外的自定义标量在最终.graphql文件中的声明形态由 React 组件ScalarType生成见 scalar-type.tsxreturn ( gql.ScalarType name{props.type.name} description{doc} specifiedByUrl{props.specificationUrl} / );这里description取自 TypeSpec 中标量的文档注释getDocspecifiedByUrl则来自标量的specifiedBy装饰器或标量映射表中的specificationUrl。specifiedBy装饰器的实现见 specified-by.ts它将 URL 存入 per-Program 的状态映射而在 mutation 阶段scalar.ts优先使用源标量上显式声明的specifiedBy否则回退到映射表中的 URL——由于ID的映射表条目不含specificationUrl且ID本身不需要自定义标量声明因此它不会触发任何specifiedBy输出。小结数据类型所属命名空间用途关键源码IDTypeSpec.GraphQL标识 GraphQL 内置 ID 标量派生标量沿extends链识别后改写为IDscalars.tsp、scalar.tsSchemaOptionsTypeSpec.GraphQL.Schemaschema装饰器参数name决定多 schema 输出文件名默认schemaschema.tsp、schema.ts如需进一步了解typespec/graphql提供的装饰器如compose、graphqlInterface、schema的完整参数说明可继续阅读仓库中的 decorators.md 与 emitter.md映射表的逐项行为则可通过测试 scalar-mappings.test.ts 自行运行验证。【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表