关于 trpc
面向编写或审查 tRPC v11 代码的 Agent 技能,整理 React 集成、迁移、路由、传输、SSR 和订阅中的版本特定决策与陷阱。
主要功能
- 01tRPC v11 API 指引
- 02v10 到 v11 迁移说明
- 03路由器与过程构建模式
- 04错误与验证指导
- 05传输与批处理注意事项
- 06SSR 与订阅模式
适用场景
- 01审查 tRPC v11 代码
- 02将项目从 tRPC v10 迁移
- 03添加文件上传或订阅
- 04排查预取与批处理问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill trpc安装后在 Claude Code 中输入/trpc确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mdclient-derive-query-keys.mdclient-invalidate-with-query-filters.mdclient-subscription-options.mdclient-tanstack-integration.mderr-format-standard-schema-issues.mderr-nullish-cursor.mderr-output-strips-fields.mderr-set-isdev-explicitly.mdlink-cap-batch-size.mdlink-default-to-httpbatchlink.mdlink-endpoint-matches-mount-path.mdlink-gate-cache-headers.mdlink-read-batch-headers-from-oplist.mdlink-route-subscriptions-separately.mdlink-scope-body-parsers.mdlink-transformer-on-terminating-links.mdmig-await-get-raw-input.mdmig-formdata-is-native.mdmig-renamed-type-exports.mdmig-typescript-version-floor.mdproc-concat-over-standalone-middleware.mdproc-input-before-use.mdproc-merge-only-object-inputs.mdproc-narrow-ctx-in-middleware.mdproc-single-trpc-instance.mdrsc-dehydrate-pending-queries.md详细介绍
tRPC v11
tRPC 强制要求做出的决策,以及如何解决这些问题。本文旨在让 Agent 在编写或审查代码时应用这些规则。每条规则都会指出它要纠正的错误默认做法;对于模型已经能正确处理的情况,不设规则。
本文固定针对 tRPC v11,并已根据 11.18.0(2026-06-17)验证。 不存在 v12——但此处有几个 API 带有 @deprecated … will be removed in v12 标记,目前仍在发布。依赖版本:typescript >=5.7.2、@tanstack/react-query ^5.80.3、react >=18.2.0。
何时应用
在以下情况下使用此技能:
- 代码导入了
initTRPC、createTRPCContext、createTRPCOptionsProxy、createTRPCReact、createTRPCClient、httpBatchLink、httpSubscriptionLink、splitLink、fetchRequestHandler、createCallerFactory或TRPCError——或使用.input()/.output()/.use()/.query()/.mutation()/.subscription()定义过程 - 用户提到“所有类型都变成了
any”、“失效处理不起作用”、“contextMap[utilName] is not a function”、“transformer 属性换了位置”、“仪表板上出现 414 / 413”、“订阅无法连接”、“预取没有完成水合”,或“每个过程都返回 404” - 将代码库从 tRPC v10 迁移过来,或审查基于 v10 时代示例编写的 tRPC 代码——这是收益最高的时机,因为推荐的 React 客户端已变更,而陈旧代码往往仍能编译通过
- 为现有路由器添加第一个订阅、第一个文件上传或第一个 RSC 预取——每种情况都会涉及一个 v11 已彻底取代 v10 做法的领域
- 随着应用规模扩大而审查批处理客户端,因为未设上限的默认值会导致间歇性生产故障
此技能不适用于:
- TanStack Query 的一般语义——缓存生命周期、重试、
useMutation的使用体验(→tanstack-query) - 编写或迁移用作验证器的 Zod 模式(→
zod) - 超出 tRPC 处理器范围的 Next.js App Router 路由、流式传输或缓存(→
nextjs) - TypeScript 的一般类型收窄和泛型(→
typescript)
规则分类
| # | 分类 | 前缀 | 涵盖内容 |
|---|---|---|---|
| 1 | React 客户端接口 | client- | 集成方式、选项工厂、查询键、失效处理、订阅 |
| 2 | v10 → v11 差异 | mig- | 重命名、移除和惰性实例化的 API;依赖版本下限 |
| 3 | 路由器与过程构建 | proc- | 实例标识、构建器顺序、上下文收窄、输入合并 |
| 4 | 错误与验证语义 | err- | 哪些内容会暴露、哪些内容会泄露、使用哪种错误类 |
| 5 | 链接、传输与序列化 | link- | 链接链、批处理限制、转换器、适配器、缓存 |
| 6 | SSR、RSC 与服务端调用 | rsc- | 预取与水合、QueryClient 生命周期、调用方误用 |
| 7 | 订阅与流式传输 | sub- | 基于 SSE 的异步生成器、身份验证、保活、积压竞态 |
快速参考
1. React 客户端接口
client-tanstack-integration— 使用@trpc/tanstack-react-query构建 React 数据获取;如今createTRPCReact是经典用法client-invalidate-with-query-filters— 新代理上没有useUtils();通过queryClient+pathFilter()/queryFilter()进行失效处理client-derive-query-keys— 新代理上没有getQueryKey();键可通过代理上的queryKey()/pathKey()/infiniteQueryKey()获取client-subscription-options— 新代理上没有.useSubscription();将subscriptionOptions()传给@trpc/tanstack-react-query中的useSubscription
2. v10 → v11 的差异
mig-formdata-is-native— 六个experimental_*上传 API 均已移除;FormData 是splitLink后面的原生输入mig-renamed-type-exports—AnyRouter→AnyTRPCRouter等;inferRouterInputs/Outputs没有变化mig-await-get-raw-input—rawInput为undefined;输入是惰性读取的,因此要使用await getRawInput()mig-typescript-version-floor— TS>=5.7.2,如果编辑器使用不同版本的 TS,所有类型都会悄悄变成any
3. Router 与 Procedure 构建
proc-narrow-ctx-in-middleware— 裸调用next()会让ctx.user保持为可空,因此守卫条件会被!强制断言掉proc-input-before-use— 在.input()之前调用.use(),会让中间件处理未经验证的输入proc-single-trpc-instance— 每个应用只使用一个initTRPC.create();实例不匹配会导致mergeRouters在运行时抛出错误proc-merge-only-object-inputs— 只有对象模式会合并;其他类型都会悄悄替换之前的解析器proc-concat-over-standalone-middleware—experimental_standaloneMiddleware已弃用,且无法声明.input();请使用.concat()
4. 错误与验证语义
err-format-standard-schema-issues— 解析器按顺序分派,因此仅支持 Zod 的errorFormatter会对 Valibot / Effect(StandardSchemaV1Error)以及 ArkType(ArkErrors)返回nullerr-output-strips-fields—.output()返回解析后的值,因此会剥离未知键;其失败会返回 500,而不是 4xxerr-nullish-cursor—.optional()游标只会在失效后返回 400;请使用.nullish()err-set-isdev-explicitly— 如果未显式设置isDev,边缘运行时会将error.data.stack发送给每个客户端
5. 链路、传输与序列化
link-transformer-on-terminating-links— transformer 已移入链路;为消除带品牌类型错误而删除它,会导致运行时的Date出错link-route-subscriptions-separately—httpBatchLink会直接拒绝订阅操作link-cap-batch-size—maxItems和maxURLLength默认为Infinity;请将它们与服务端的maxBatchSize配合使用link-gate-cache-headers— 批处理加上不加区分的responseMeta缓存,会导致 CDN 将一个用户的数据提供给另一个用户link-default-to-httpbatchlink—httpBatchStreamLink开始流式传输后无法设置响应头;它不是默认选项link-read-batch-headers-from-oplist— 批处理链路传入的是{ opList },而不是{ op };解构错误会导致每个请求都返回 401link-scope-body-parsers— 全局express.json()会在 tRPC 读取流之前将其耗尽link-endpoint-matches-mount-path—endpoint是 tRPC 会剥离的前缀;不匹配会导致所有 procedure 都返回 404
6. SSR、RSC 与服务端调用
rsc-query-client-per-request— 模块作用域的QueryClient会将一位用户的缓存提供给下一次请求rsc-dehydrate-pending-queries— 如果没有 pending 覆盖,void prefetchQuery永远无法到达客户端rsc-prefetch-through-options-proxy— 调用方的结果永远不会进入缓存,因此客户端会再次获取所有数据rsc-share-logic-not-callers— 嵌套调用方会重新创建上下文,并重新运行整个中间件链
7. 订阅与流式传输
sub-write-async-generators—observable()已弃用并将移除,只有生成器支持tracked()的断线重连与恢复sub-keep-credentials-out-of-urls—connectionParams会将令牌序列化到查询字符串中,也会写入所有记录该字符串的日志sub-enable-sse-keepalive—ping.enabled默认值为false,因此空闲的 SSE 流会被代理清理,并被视为不稳定的网络连接sub-attach-listener-before-backlog— 先获取历史记录再附加监听器,只会在生产负载下导致事件丢失
使用方法
遇到相关决策时,阅读对应的参考文件。每条规则都会指出它要纠正的错误默认做法,然后展示规范方式;只有当错误做法确实容易踩坑时,才会对比错误与正确的做法。
建议先了解以下两条捷径:
-
正在审查或迁移现有的 tRPC 代码? 从
client-和mig-开始。过时的代码往往仍能编译,因此不会有任何提示引导你查看这些内容;但其他所有内容都以它们为基础。 -
正在强化已能正常运行的功能? 与安全相关的规则包括
link-gate-cache-headers、rsc-query-client-per-request、err-set-isdev-explicitly、proc-input-before-use和sub-keep-credentials-out-of-urls。 -
章节定义 — 分类结构与排序依据
-
规则模板 — 用于添加新规则
-
AGENTS.md — 自动生成的所有规则目录
相关技能
tanstack-query— tRPC 的 React 客户端现在委托给它处理的查询层;它拥有本技能所依赖的缓存语义zod— 验证器编写与 Zod 4 差异,包括本技能仅作提示的.flatten()→z.treeifyError()变更typescript— 超出 tRPC 推断范围的一般类型级工作