如何在GraphQL解析器内获取返回类型?能否访问__typename?
在GraphQL解析器中自动获取__typename对应的类型名
问题背景
使用graphql-parse-resolve-info库判断字段是否被请求时,目前需要手动传入解析器对应的类型名(比如Thing1),想通过自动获取该类型名避免手动操作。尝试过info.returnType.toString(),但结果会包含数组、非空标记等额外字符,解析起来不可靠。
解决方案:用GraphQL官方工具函数提取纯类型名
GraphQL.js内置了getNamedType工具函数,能自动剥离List、NonNull等包装类型,直接拿到底层的命名类型,再取其name属性即可得到对应__typename的字符串。
改造后的代码
import { parseResolveInfo } from 'graphql-parse-resolve-info' import { getNamedType } from 'graphql' // 改造fieldWasRequested,不再需要手动传type参数 export const fieldWasRequested = (field: string, info: GraphQLResolveInfo) => { // 提取去掉包装的纯命名类型 const namedType = getNamedType(info.returnType) const typeName = namedType.name const parsedInfo = parseResolveInfo(info) const fields = parsedInfo?.fieldsByTypeName?.[typeName] ?? {} return field in fields } // 使用示例:无需传入类型名 export const thing1: Resolvers['thing1'] = async (parent, args, ctx, info): Promise<Thing1[]> => { const isField1Requested = fieldWasRequested('field1', info) // 后续业务逻辑... }
可选:增加类型校验(避免非对象类型场景)
如果需要确保拿到的是对象类型(毕竟只有对象类型才有字段),可以配合isObjectType工具函数做校验:
import { getNamedType, isObjectType } from 'graphql' export const fieldWasRequested = (field: string, info: GraphQLResolveInfo) => { const namedType = getNamedType(info.returnType) // 仅处理对象类型的情况 if (!isObjectType(namedType)) { return false } const typeName = namedType.name const parsedInfo = parseResolveInfo(info) const fields = parsedInfo?.fieldsByTypeName?.[typeName] ?? {} return field in fields }
为什么这个方法可靠
getNamedType是GraphQL官方提供的工具函数,专门用来处理各种包装类型的嵌套场景,不管返回类型是单个对象、数组还是带非空约束的类型,都能精准提取出核心的类型名称,完全不需要手动解析字符串,从根源上避免了手动解析的脆弱性。
内容的提问来源于stack exchange,提问作者nonethewiser
相关产品推荐
相关产品推荐

