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

