middleware icon indicating copy to clipboard operation
middleware copied to clipboard

zValidator types not working with rpc client query

Open wststone opened this issue 1 year ago • 8 comments

image image image As shown in the screenshots above, the rpc client query paramters should have the correct inferred number type.

package version: "hono": "^4.5.4" "@hono/zod-validator": "^0.2.2"

wststone avatar Aug 23 '24 12:08 wststone

Bump! I have the same issue.

cybercoder-naj avatar Sep 08 '24 05:09 cybercoder-naj

Hi @wststone @cybercoder-naj

The Zod Validator uses z.input to infer a query using the request type. With it, the value with z.coerce will have undefined and optional:

CleanShot 2024-09-10 at 16 10 58@2x

This means the value defined z.coerce can be optional or undefined. On the other hand, if you specify the value with z.number(), it can not allow undefined.

yusukebe avatar Sep 10 '24 07:09 yusukebe

bump, what to do?

Pyakz avatar Oct 23 '25 14:10 Pyakz

@yusukebe i may be wrong here, but i think OP was asking about how the input is inferred client side.

while (i expect) values are typed correctly in the request handler, param and query options are typed as strings in the client arguments.

while i'm not sure how this happens type-wise, i assume it's because param and query values are necessarily stringified when going over the wire. is this correct?

_edit: specifically, i'm guessing it's the typing of ValidationTargets

// server
const ZQuery = z.object({
  page: z.coerce.number(),
})

const app = new Hono()
  .get('/',  zValidator('query', ZQuery), async (c) => {
      const { page } = c.req.valid('query') // number
      // ...
   })

// client
const client = hc<typeof app>('')
const response = await client.index.$get({
  page: 1, // expects string
})

parenthetically, i'm a little confused by what you said about z.coerce: as far as i can tell, it results in a number type, which makes sense because i think even undefined gets coerced to 0.

ambergristle avatar Oct 23 '25 15:10 ambergristle

Hi @ambergristle

I'm not sure what the problem 100%, but the page in the client being string is correct behavior because it is already "string" in the client request.

yusukebe avatar Oct 27 '25 10:10 yusukebe

hey @yusukebe! i'm not sure i understand what you meant by this

the page in the client being string is correct behavior because it is already "string" in the client request

do you mean that the client types param and query values as string because they have to be converted to strings when making the request?

ambergristle avatar Oct 29 '25 14:10 ambergristle

do you mean that the client types param and query values as string because they have to be converted to strings when making the request?

Yes, yes!

yusukebe avatar Oct 29 '25 15:10 yusukebe

sounds like this isn't an issue then, maybe just an opportunity to add some detail to the docs. i'll open a pr next week

edit

  • opened a PR to document this behavior: https://github.com/honojs/website/pull/775
  • i found a rejected proposal to have the RPC client stringify query data. thought it might be helpful context: https://github.com/honojs/hono/issues/3495

ambergristle avatar Nov 01 '25 05:11 ambergristle