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

如何像apollo-client那样全局处理GraphQL联合类型解决TypeScript报错

解决方案

核心原因:Apollo Client默认会自动在所有查询的对象类型中插入__typename字段,配合graphql-codegen的Apollo相关插件会自动处理联合类型的类型窄化,而graphql-request默认不会做这个处理,所以才会出现类型报错。

你可以通过以下几步实现类似Apollo的全局处理,无需重复手写类型判断:

1. 配置graphql-codegen自动插入__typename并生成类型守卫

更新你的codegen.yml配置,启用自动插入__typename和类型守卫生成能力:

schema: ./schema.graphql
documents: ./src/**/*.graphql
generates:
  ./src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-react-query
      - typescript-type-guards # 自动生成所有联合类型、接口的类型守卫函数
    config:
      addTypename: true # 自动给所有查询的对象添加__typename字段
      omitOperationSuffix: true
      reactQueryVersion: 4 # 匹配你实际使用的react-query版本

安装缺失的依赖:

npm i -D @graphql-codegen/typescript-type-guards

2. 全局封装graphql-request自动适配类型

封装全局的graphql-request实例,配合codegen自动生成的Sdk,所有请求的返回值会自动携带正确的窄化类型:

import { GraphQLClient } from 'graphql-request';
import { getSdk } from './generated/graphql';

const client = new GraphQLClient('/api/graphql', {
  headers: {
    // 你的全局请求头配置
  }
});

// 所有业务请求统一使用这个sdk调用,返回值类型已自动处理
export const gqlSdk = getSdk(client);

3. 自动生成的类型守卫使用(仅特殊场景需要)

如果遇到需要手动区分联合类型的场景,直接调用codegen生成的类型守卫函数即可,无需自己实现判断逻辑:

import { isImage, isEmoji } from './generated/graphql';

if (isImage(object.logo)) {
  // 此处TS会自动识别object.logo为Image类型,可直接访问url字段
  console.log(object.logo.url);
} else {
  // 此处TS会自动识别object.logo为Emoji类型
  console.log(object.logo.emoji);
}

免判断特殊配置(不推荐,会丢失类型安全)

如果你确定业务中所有Media类型的Image字段一定存在,可以在codegen中配置自定义类型映射跳过类型判断:

config:
  mappers:
    Media: '{ __typename: "Image" } & Omit<Image, "__typename"> | { __typename: "Emoji" } & Omit<Emoji, "__typename">'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:24:03