H
Hono2mo ago
Parker

Discriminated Unions from AppType

Hi there! I had a question about the returned type of hc<typeof app>. I have an API route that returns 400 and { success: false, error: SomeTypes } . Generally I would expect this to create a discriminated union on result.ok or on body.success (or both!) but neither seems to work. This seems to be related to returning c.json() multiple times in my route, but in theory I would expect this to consolidate types. I've attached some screenshots as an example. In the last screenshot instead of success: boolean it should be a literal, success: false which would allow me to use it as a discriminate. Would love any insight folks have!
No description
No description
No description
2 Replies
ambergristle
ambergristle2mo ago
discriminating by status code works:
import { Hono } from 'hono'
import { hc } from 'hono/client'

const app = new Hono()
.get('/', (c) => {
if (false) {
return c.json({ error: {} }, 400)
}

return c.json({ data: {} }, 200)
})

export default app;

const client = hc<typeof app>('')
const response = await client.index.$get()

if (response.ok) {
const { data } = await response.json()
} else {
const { error } = await response.json()
}
import { Hono } from 'hono'
import { hc } from 'hono/client'

const app = new Hono()
.get('/', (c) => {
if (false) {
return c.json({ error: {} }, 400)
}

return c.json({ data: {} }, 200)
})

export default app;

const client = hc<typeof app>('')
const response = await client.index.$get()

if (response.ok) {
const { data } = await response.json()
} else {
const { error } = await response.json()
}
also including a success flag in the response data might be overkill, but if you really want to, you'd need to set it as a literal:
return c.json({
success: false as const,
// ...
}, 400)
return c.json({
success: false as const,
// ...
}, 400)
Parker
ParkerOP2mo ago
Thank you! Yeah I figured out last night that I can discriminate on status code and it works!

Did you find this page helpful?