No Types for RPC with abstracted routes
I'm not getting any type hints from my Hono RPC client. I know there are warnings not to use the factory method, but as far as I knew this was the only way to have abstracted routes, which I find pretty important for organizing many routes.
30 Replies
hey! where have you seen warnings not to use the factory method?
from the docs, that seems to be the right approach for your goal: https://hono.dev/docs/guides/best-practices#factory-createhandlers-in-hono-factory
are you chaining methods in the route apps?
Are you doing the same pattern? And are you finding that type hinting for the RPC methods work?
i haven't used either the factory or rpc extensively
Yeah I'm chaining my methods, but for whatever reason my types dont' show up for the RPC
I'm surprised there isn't a full tutorial or documentation on this pattern
so, i reproed your example locally, and the client intellisense is working fine
what type inference isn't working as expected?
Hm, for me the response types for json come back as type never
probably because i mocked your routes to repro
try starting w a minimal example + scaling up. that should help identify the breaking code
is it a specific route/endpoint that's not working, or is it all of them?
Oh it's a specific endpoint that's screwed up. Let's say I'm doing type
A | undefined
. Should that come back as type never?
Removing undefined by throwing fixes the type problem and will give me back the rich type A
I would've expected something like type discrimination where I get to check if a type is undefined at the other point, and if not then it's A
it's hard to say from such a generic example
it would be helpful if you shared the handler code, along with what you'd like/expect the return type to be
but Hono RPC only works with
json
or text
responses, and if you try to mix in a c.body
, that will break your typing
tl;dr - when you do a union like WhateverType | any
, in some cases that will effectively get flattened to any
RPC needs a contentful response, type to work, so if you're not returning c.text
or c.json
, i would expect you to have ts problems
https://github.com/honojs/hono/blob/d72aa4b6d77c7b3150bf2b7bae001e6635fe98ae/src/types.test.ts#L2332
In this example, the database has a chance of returning undefined. And IMO
undefined | T
should be the return type without using empty
.
If I remove the empty
logic then it'll be return type never
!
Which IMO makes very very little sense
So now I'm adding extra Hono-specific logic just to appease the type system, which I didn't have to do with Elysia
I should be able to discriminate on the other side with if (x !== undefined) {...}
Even weirder is that if I return []
or {}
that also counts as returning type never
!
Shouldn't that be never[]
and not simply never
?interesting. so you're grabbing the first element using
at
, which i would also expect to yield T | undefined
Yup, it is
Even weirder is that I can simply do
return c.json({})
and it'll say that's type neverohhhhhhhh
yo
Did I do something retarded
this is invalid, i think:
c.json(undefined)
try nesting
or using null
???
But empty object is valid JSON...
Sometimes you want to return empty array
but that's not what
row.at(0)
returns
Yup so I do
?? []
or ?? {}
if you do this instead:
i'd expect it to work fine
Ohh
I see
Okay that works as a workaround
Thanks so much
or you can use
null
But IMO...
c.json({})
shouldn't be never
!!!
It should just be an empty object!it's not. that's why you get it when you remove
empty
Try it directly. Create an empty route that just does
return c.json({})
I simplified it to just this
Your advice works and I'm gonna be doing that
But the above route truly does return
never
And when I inspect the response on the other end it returns an object on the other end since that's valid JSONwell i'll be damned
Ah hmm
so it's definitely intentional. i wonder why tho
They specifically ban blank objects, I see