能否为Apollo Client mutation操作中的缓存对象启用类型支持?相关技术咨询
Apollo Client mutation操作中的缓存对象启用类型支持?相关技术咨询
我太懂你这种苦恼了——每次在mutation的update里操作缓存,面对ApolloCache<any>和无类型提示的fields,手动敲字段名不仅容易出错,还完全没有IDE的智能提示,效率低得离谱!
针对你的问题,我来给你梳理下可行的方案和相关情况:
一、有没有办法启用缓存对象的类型支持?
当然有,而且有两种主流方案:
1. 用graphql-codegen自动生成类型(推荐)
你可以借助@graphql-codegen/typescript-apollo-client这个生成器,它能直接根据你的GraphQL Schema生成和缓存操作完全匹配的类型。
具体步骤很简单:
- 在你的codegen配置文件里(比如
codegen.yml)添加这个生成器:generates: src/generated/apollo-client-types.ts: plugins: - "typescript" - "typescript-operations" - "typescript-apollo-client" - 运行codegen命令生成类型文件后,你就可以导入生成的类型,替换掉默认的
ApolloCache<any>。比如在mutation的update函数里:import type { MyAppCache } from './generated/apollo-client-types'; await client.mutate({ mutation: updateNFTsOfUserProfile, update(cache: MyAppCache, { data }) { // 这里cache的所有操作都会有基于你schema的类型提示了 cache.modify({ fields: { // 这里的fields会自动提示你schema里定义的所有可用字段 userProfile(existing, { readField }) { // 甚至连existing的类型都是正确的 } } }); }, });
这种方案完全自动化,schema更新后重新生成类型就行,几乎没有维护成本。
2. 手动定义缓存类型(备选)
如果你暂时不想用codegen,也可以手动基于你的Schema定义缓存的类型,然后用类型断言来指定:
// 基于你的Schema定义缓存的根类型 type MyAppCacheType = { UserProfile: { id: string; nfts: NFT[]; // 其他你需要的字段 }; // 其他根类型 }; // 自定义带类型的Cache类型 type TypedApolloCache = ApolloCache<MyAppCacheType>; await client.mutate({ mutation: updateNFTsOfUserProfile, update(cache: TypedApolloCache, { data }) { // 这里cache就有你手动定义的类型提示了 }, });
不过这种方法的缺点很明显:每次Schema变更都要手动同步更新类型,时间长了很容易出现类型和实际Schema不一致的情况,只适合小项目或者临时场景。
二、这是已知限制还是可支持的功能?
这其实是Apollo Client早期的一个常见痛点,但现在已经不是无法解决的限制了:
- 早期Apollo Client核心确实没有自带缓存的类型推导,这是因为缓存的结构和Schema虽然相关,但存在归一化等处理,直接内置类型支持复杂度较高
- 不过现在通过graphql-codegen的社区生态,已经能完美实现基于Schema的缓存类型提示,这也是目前社区最推荐的方案
- Apollo官方现在也在逐步优化类型相关的体验,比如在新版本中对codegen的支持更友好,只是这部分内容更多是通过生态工具实现,所以官方文档里可能没有专门大篇幅讲解
内容来源于stack exchange
相关产品推荐
相关产品推荐

