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

GraphQL调用body中使用三元运算符的TypeScript类型适配问题

解决GraphQL复用请求的TypeScript类型错误问题

问题原因

你遇到的类型错误是因为三元运算符返回了string | FormData的联合类型,但代码中某个位置(比如请求配置的类型定义)约束了body必须是FormData,导致TS无法自动兼容两种类型。下面是几种可行的解决方法:


方法1:分支逻辑拆分(最严谨)

直接通过if/else分支分别处理带文件和不带文件的情况,让TypeScript能准确推断每个分支的类型,避免联合类型冲突:

async function graphqlRequest(query: string, variables?: Record<string, any>, fileBlob?: Blob) {
  // 带文件的情况:构造FormData
  if (fileBlob) {
    const formData = new FormData();
    // 按照GraphQL文件上传的标准格式组装数据
    formData.append('operations', JSON.stringify({ query, variables }));
    formData.append('map', JSON.stringify({ '0': ['variables.file'] }));
    formData.append('0', fileBlob);

    return fetch('/graphql', {
      method: 'POST',
      body: formData
    });
  }

  // 不带文件的情况:发送JSON请求
  return fetch('/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables })
  });
}

方法2:类型断言(快速临时解决)

如果不想重构逻辑,可以用类型断言明确告诉TS当前body的类型,但要确保你的三元运算符逻辑是正确的(即fileBlob存在时一定是FormData,否则是string):

const queryData = { query: 'your-graphql-query', variables: {} };
const fileBlob: Blob | undefined = /* 你的文件Blob */;

const body = fileBlob ? (() => {
  const formData = new FormData();
  formData.append('operations', JSON.stringify(queryData));
  formData.append('map', JSON.stringify({ '0': ['variables.file'] }));
  formData.append('0', fileBlob);
  return formData;
})() : JSON.stringify(queryData);

fetch('/graphql', {
  method: 'POST',
  headers: fileBlob ? {} : { 'Content-Type': 'application/json' },
  // 断言为string | FormData,匹配fetch的body参数类型
  body: body as string | FormData
});

方法3:定义明确的联合类型配置

先定义包含两种请求配置的联合类型,再分别构造对应配置,最后合并到请求中:

// 定义两种请求配置的联合类型
type GraphqlRequestConfig = 
  | { headers: { 'Content-Type': 'application/json' }, body: string }
  | { headers?: never, body: FormData };

async function graphqlRequest(query: string, variables?: Record<string, any>, fileBlob?: Blob) {
  let requestConfig: GraphqlRequestConfig;

  if (fileBlob) {
    const formData = new FormData();
    formData.append('operations', JSON.stringify({ query, variables }));
    formData.append('map', JSON.stringify({ '0': ['variables.file'] }));
    formData.append('0', fileBlob);
    requestConfig = { body: formData };
  } else {
    requestConfig = {
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query, variables })
    };
  }

  return fetch('/graphql', {
    method: 'POST',
    ...requestConfig
  });
}

内容的提问来源于stack exchange,提问作者typescriptBeginner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:05:20