Hono中Input类型推断错误,客户端无法传递json参数
Hono客户端调用
$patch时无法传入json参数的类型问题 问题重现
我的Hono应用路由定义:
const app = new Hono().patch("/books/title/:bookId", booksTitleRoute.PATCH) export type AppType = typeof app;
路由处理器实现:
export async function PATCH(c: Context) { const bookId = uuidSchema.parse(c.req.param("bookId")); const payload = await c.req.json(); const { title } = booksTitleSchema.parse(payload); const user = c.get("user"); // ... 后续业务逻辑 return c.json({ message: "Book title updated" }); }
但生成的AppType中,$patch方法的类型只包含param参数:
$patch: (args: { param: { bookId: string; }; }, options?: ClientRequestOptions<unknown> | undefined) => Promise<ClientResponse<{ message: string; }, ContentfulStatusCode, "json">>
使用Hono客户端发起请求时,添加json参数会触发TypeScript错误:
client["books"]["title"][":bookId"].$patch({ param: { bookId }, json: { title: newTitle }, // 这里报错 }),
错误提示:
Object literal may only specify known properties, and 'json' does not exist in type '{ param: { bookId: string; }; }'.ts(2353)
问题根源
Hono的类型推导依赖显式的请求体声明。当前路由处理器只是手动解析并校验请求体,但没有通过Hono官方的验证器机制告知类型系统该路由需要接收JSON请求体,导致客户端类型中缺失json参数的定义。
解决办法
1. 使用Hono验证器声明请求体(推荐)
通过@hono/zod-validator这类验证器中间件,显式定义请求体的Schema,Hono会自动推导客户端所需的json参数类型,同时还能自动完成请求体校验,省去手动调用parse的步骤。
修改路由定义:
import { zValidator } from "@hono/zod-validator"; const app = new Hono() .patch( "/books/title/:bookId", zValidator("json", booksTitleSchema), // 声明JSON请求体的Schema booksTitleRoute.PATCH ); export type AppType = typeof app;
更新路由处理器,直接获取已校验的请求体:
export async function PATCH(c: Context) { const bookId = uuidSchema.parse(c.req.param("bookId")); // 直接拿到已通过校验的请求体 const { title } = c.req.valid("json"); const user = c.get("user"); // ... 业务逻辑 return c.json({ message: "Book title updated" }); }
这样修改后,AppType中的$patch方法会自动包含json参数的类型,客户端调用时就不会再报错。
2. 手动扩展客户端类型(临时方案)
如果暂时不想大规模重构路由,可以手动扩展客户端类型来兼容json参数,但这种方式需要手动维护类型一致性,不推荐长期使用:
import type { AppType } from "./你的应用文件路径"; import type { z } from "zod"; // 扩展$patch方法的类型 type ExtendedBookTitlePatch = { $patch: ( args: { param: { bookId: string }; json: z.infer<typeof booksTitleSchema>; }, options?: ClientRequestOptions<unknown> ) => ReturnType<AppType["client"]["books"]["title"][":bookId"]["$patch"]>; }; // 类型断言扩展客户端 const client = new HonoClient<AppType>({ /* 客户端配置 */ }) as unknown as ExtendedBookTitlePatch;
内容的提问来源于stack exchange,提问作者Lenny
相关产品推荐
相关产品推荐

