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
相关产品推荐
相关产品推荐

