You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:27:02