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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 06:13:10