使用抽象路由时Hono RPC无类型提示,求支持路由拆分的解决方案
解决Hono RPC客户端类型提示缺失的路由拆分方案
放弃使用createFactory,直接通过主App实例挂载子路由的方式实现路由拆分,同时保留完整的类型推导能力,具体实现如下:
1. 定义环境变量类型(env.ts)
// 假设db/mqtt/redis已提前初始化 import { db, mqtt, redis } from './your-services' export type Env = { Variables: { db: typeof db mqtt: typeof mqtt redis: typeof redis } }
2. 创建主App实例(app.ts)
直接初始化Hono主应用,挂载全局中间件,再导入并挂载各个子路由:
import { Hono } from 'hono' import { Env } from './env' import root from './routes/root' import config from './routes/config' import redisRoutes from './routes/redis' // 初始化主App,指定Env类型 const app = new Hono<Env>() // 全局中间件:注入环境变量 app.use(async (ctx, next) => { ctx.set('db', db) ctx.set('mqtt', mqtt) ctx.set('redis', redis) await next() }) // 挂载拆分的子路由 app.route('/', root) app.route('/config', config) app.route('/redis', redisRoutes) // 导出App类型,供客户端使用 export type App = typeof app export default app
3. 拆分的子路由示例(比如routes/redis.ts)
每个子路由创建独立的Hono实例,定义对应路径的接口:
import { Hono } from 'hono' import { Env } from '../env' // 创建子路由,继承主App的Env类型 const redisRoutes = new Hono<Env>() // 定义接口,类型会自动被主App收集 redisRoutes.get('/info', async (ctx) => { const redisClient = ctx.get('redis') const info = await redisClient.info() return ctx.json({ info }) }) redisRoutes.post('/set', async (ctx) => { const { key, value } = await ctx.req.json() await ctx.get('redis').set(key, value) return ctx.json({ success: true }) }) export default redisRoutes
4. RPC客户端使用(client.ts)
直接导入主App的App类型,传入hc即可获得完整的类型提示:
import { hc } from 'hono/client' import type { App } from './app' const client = hc<App>(`http://${HOSTNAME}:${PORT}`) // 此时client会自动提示所有路由接口,比如: // client.redis.info.$get() // client.redis.set.$post({ json: { key: 'foo', value: 'bar' } })
核心原理
直接通过new Hono()创建主应用和子路由,Hono的类型系统会自动合并所有挂载的子路由类型,导出的App类型包含了完整的路由、请求/响应结构信息,RPC客户端hc就能基于此提供准确的类型提示。
内容的提问来源于stack exchange,提问作者Meow
相关产品推荐
相关产品推荐

