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

Apollo GraphQL subscribeToMore未接收订阅数据,subscriptionData异常

问题:updateQuery参数中subscriptionData接收查询数据而非订阅数据的原因与解决方法

可能原因

  • TypeScript类型推断关联错误:subscribeToMore是从useHomePageQuery这个查询Hook返回的,Apollo Client的TypeScript类型系统会默认把subscriptionData的类型和当前查询的返回类型(HomePageQuery)绑定,而没有自动识别你传入的订阅文档的实际返回类型。
  • 代码生成工具配置问题:如果用了GraphQL Codegen之类的工具生成类型,可能配置里没正确区分订阅操作和查询操作,导致订阅的返回类型被错误复用了查询的HomePageQuery类型。
  • 订阅Schema结构巧合:你的订阅返回的字段结构和HomePageQuery的结构完全一致,导致类型系统无法区分,自动匹配了已有的查询类型。

解决方法

1. 手动指定subscribeToMore的泛型类型

明确告诉TypeScript订阅操作的返回类型,覆盖默认的推断:

// 先定义订阅的返回类型(可从代码生成的类型中获取,或手动定义)
type HomePageRemoteChargeCreatedSubscription = {
  remoteChargeCreated: {
    remoteCharge: {
      id: string;
      station: {
        id: string;
        name: string;
      };
    };
  };
};

// 在subscribeToMore时指定泛型参数
subscribeToMore<HomePageQuery, HomePageRemoteChargeCreatedSubscription>({
  document: gql`
    subscription HomePageRemoteChargeCreated($userId: ID!) {
      remoteChargeCreated(userId: $userId) {
        remoteCharge {
          id
          station {
            id
            name
          }
        }
      }
    }
  `,
  updateQuery: (prev, { subscriptionData }) => {
    // 此时subscriptionData.data的类型已正确对应订阅返回结构
    if (!subscriptionData.data) return prev;
    const createdRemoteCharge = subscriptionData.data.remoteChargeCreated;

    return {
      me: {
        ...prev.me,
        account: {
          ...prev.me?.account,
          accountUser: {
            ...prev.me?.account?.accountUser,
            currentRemoteCharge: {
              id: createdRemoteCharge?.remoteCharge.id,
              station: { ...createdRemoteCharge.remoteCharge.station },
            },
          },
        },
      },
    };
  },
  variables: {
    userId: currentUserId,
  },
});

2. 修复GraphQL代码生成配置

如果使用GraphQL Codegen生成类型,检查配置文件是否正确包含订阅操作的生成规则。示例配置片段:

// codegen.ts示例配置
generates: {
  './src/generated/graphql.ts': {
    schema: './schema.graphql',
    documents: ['./src/**/*.{ts,tsx}'],
    plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
    config: {
      skipTypename: false,
      withHooks: true,
      // 确保订阅操作生成独立类型,不与查询类型混淆
    },
  },
}

重新生成类型后,订阅的返回类型会被正确生成(比如HomePageRemoteChargeCreatedSubscription),直接在subscribeToMore中使用该类型即可。

3. 验证订阅Schema的正确性

检查服务器端的GraphQL订阅Schema,确认remoteChargeCreated字段的返回类型没有意外与HomePageQuery结构完全一致。若结构确实相似,仍需通过手动指定泛型来明确类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:25:17