使用GraphQL Code Generator时如何将自定义标量类型映射到TypeScript类型
你当前的配置仅实现了类型层面的静态映射,没有添加运行时的序列化/反序列化逻辑,因此会出现类型定义和实际运行值不符的问题,完整解决步骤如下:
步骤1:调整codegen.yml配置
保持原有的类型映射,新增strictScalars配置避免标量类型 fallback 为any:
overwrite: true schema: 'http://mybackenurl/graphql' documents: 'src/**/*.graphql' generates: src/generated/graphql.ts: config: exposeQueryKeys: true exposeFetcher: true fetcher: '../GraphQLFetcher#fetcher' strictScalars: true # 新增,严格校验标量类型 scalars: Date: Date # 保留,将Date标量静态映射为TS Date类型 plugins: - 'typescript' - 'typescript-operations' - 'typescript-react-query'
步骤2:在自定义fetcher中添加日期转换逻辑
你需要在数据请求的响应阶段把ISO 8601字符串转为Date对象,如果有提交Date类型的需求,还要在请求发起前把Date对象序列化为ISO字符串。
在你配置的../GraphQLFetcher文件中添加如下逻辑:
// 匹配ISO 8601格式日期的正则 const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d*)?(?:[-+]\d{2}:?\d{2}|Z)$/; // 反序列化:后端返回的字符串转Date对象 function deserializeDates(obj: unknown): unknown { if (typeof obj === 'string' && ISO_DATE_REGEX.test(obj)) { return new Date(obj); } if (typeof obj !== 'object' || obj === null) { return obj; } if (Array.isArray(obj)) { return obj.map(item => deserializeDates(item)); } const processed: Record<string, unknown> = {}; for (const [key, value] of Object.entries(obj)) { processed[key] = deserializeDates(value); } return processed; } // 序列化:提交给后端的Date对象转ISO字符串 function serializeDates(obj: unknown): unknown { if (obj instanceof Date) { return obj.toISOString(); } if (typeof obj !== 'object' || obj === null) { return obj; } if (Array.isArray(obj)) { return obj.map(item => serializeDates(item)); } const processed: Record<string, unknown> = {}; for (const [key, value] of Object.entries(obj)) { processed[key] = serializeDates(value); } return processed; } // 修改原有fetcher,集成转换逻辑 export async function fetcher<TData, TVariables>( document: string, variables?: TVariables ): Promise<TData> { // 序列化请求参数中的Date对象 const processedVars = variables ? serializeDates(variables) as TVariables : undefined; const resp = await fetch('http://mybackenurl/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: document, variables: processedVars }) }); const result = await resp.json(); // 反序列化响应中的日期字符串为Date对象 return deserializeDates(result.data) as TData; }
完成上述配置后,生成的类型和运行时的实际值就可以保持一致了。如果你的业务场景中日期格式有特殊规则,调整正则或者转换逻辑即可。
内容的提问来源于stack exchange,提问作者David Berg
相关产品推荐
相关产品推荐

