# 类型化路由

URL: https://caijiao.org/hono/03-typescript/01-typed-routes
Source: docs/hono/03-typescript/01-typed-routes.md
Description: 学习在 Hono 中使用 TypeScript 编写类型化参数、请求体、响应结果和模块化路由。

Hono 本身使用 TypeScript 编写。合理使用类型可以让路由参数、请求体和共享变量更清晰。

## 路由参数类型

`c.req.param()` 返回字符串。你需要自己处理数字转换和非法值：

```ts
app.get('/users/:id', (c) => {
  const id = Number(c.req.param('id'))

  if (!Number.isInteger(id) || id <= 0) {
    return c.json({ message: 'Invalid user id' }, 400)
  }

  return c.json({ id })
})
```

不要把 `Number()` 转换藏在数据库查询里，否则错误会更晚暴露。

## 请求体类型

可以给 `c.req.json()` 标注类型：

```ts
type CreatePostInput = {
  title: string
  content: string
}

app.post('/posts', async (c) => {
  const input = await c.req.json<CreatePostInput>()

  return c.json({
    id: crypto.randomUUID(),
    title: input.title,
    content: input.content,
  })
})
```

这只是 TypeScript 编译期提示，不会自动验证运行时数据。公开 API 仍然应该使用验证器。

## Variables 类型

中间件通过 `c.set()` 传递数据时，可以声明 `Variables`：

```ts
import { Hono } from 'hono'

type Variables = {
  requestId: string
  user: {
    id: string
    role: 'admin' | 'user'
  }
}

const app = new Hono<{ Variables: Variables }>()

app.use(async (c, next) => {
  c.set('requestId', crypto.randomUUID())
  c.set('user', { id: 'u_1', role: 'admin' })
  await next()
})

app.get('/me', (c) => {
  const user = c.get('user')
  return c.json(user)
})
```

这样 `c.get('user')` 会得到明确类型。

## 子路由类型

拆分路由时可以导出子应用：

```ts
// routes/posts.ts
import { Hono } from 'hono'

export const posts = new Hono()
  .get('/', (c) => c.json([]))
  .post('/', async (c) => {
    const body = await c.req.json<{ title: string }>()
    return c.json({ id: 1, title: body.title }, 201)
  })
```

入口文件：

```ts
import { Hono } from 'hono'
import { posts } from './routes/posts'

const app = new Hono()

const routes = app.route('/posts', posts)

export type AppType = typeof routes
export default app
```

`AppType` 后续可以提供给 Hono Client，用于 RPC 类型推导。

## 类型与验证的边界

TypeScript 只能约束你写下的代码，不能保证客户端传来的 JSON 一定符合类型。建议把路由输入分成两层：

- TypeScript 类型：让编辑器和编译器帮助开发。
- 运行时验证：检查真实请求数据，返回可靠错误。

在 Hono 中，常见组合是 `@hono/zod-validator` 加 Zod schema。
