> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript

> Learn how to use TypeScript with Hono for type-safe web applications.

## Overview

Hono is built with TypeScript and provides excellent type safety out of the box. With Hono's type system, you get full autocomplete and type checking for routes, middleware, validation, and more.

## Environment Types

Define types for your application's environment variables and context variables using the `Env` type.

### Bindings

Bindings are environment-specific values (like environment variables on Cloudflare Workers):

```typescript theme={null}
import { Hono } from 'hono'

type Bindings = {
  TOKEN: string
  KV: KVNamespace
  DB: D1Database
}

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

app.get('/', (c) => {
  const token = c.env.TOKEN // typed as string
  const kv = c.env.KV // typed as KVNamespace
  return c.text('Hello!')
})
```

### Variables

Variables are values you set and get using `c.set()` and `c.get()`:

```typescript theme={null}
type Variables = {
  user: {
    id: string
    name: string
    role: 'admin' | 'user'
  }
  requestId: string
}

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

app.use('*', async (c, next) => {
  c.set('requestId', crypto.randomUUID())
  await next()
})

app.get('/profile', (c) => {
  const user = c.get('user') // fully typed!
  const requestId = c.get('requestId') // typed as string
  return c.json({ user, requestId })
})
```

### Combined Environment

```typescript theme={null}
type Env = {
  Bindings: {
    DATABASE_URL: string
    API_KEY: string
  }
  Variables: {
    user: User
    session: Session
  }
}

const app = new Hono<Env>()
```

## Type-Safe Routing

Hono infers types from your route patterns:

```typescript theme={null}
app.get('/posts/:id', (c) => {
  const id = c.req.param('id') // typed as string
  return c.json({ id })
})

app.get('/search/:category/:tag', (c) => {
  const { category, tag } = c.req.param()
  // both typed as string
  return c.json({ category, tag })
})
```

## Validation Types

Get full type safety with validation:

```typescript theme={null}
import { validator } from 'hono/validator'

app.post(
  '/users',
  validator('json', (value, c) => {
    const parsed = value as { 
      name: string
      email: string 
      age: number 
    }
    // validation logic
    if (!parsed.name) {
      return c.text('Invalid!', 400)
    }
    return parsed
  }),
  (c) => {
    const data = c.req.valid('json')
    // data is typed as { name: string, email: string, age: number }
    return c.json({ created: true })
  }
)
```

## Using Zod for Validation

Zod provides even better type inference:

```typescript theme={null}
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'

const userSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().int().min(18),
  role: z.enum(['admin', 'user']).default('user'),
})

type User = z.infer<typeof userSchema>

app.post(
  '/users',
  zValidator('json', userSchema),
  (c) => {
    const user = c.req.valid('json')
    // user is fully typed with all Zod transformations!
    return c.json({ user })
  }
)
```

## Generic Types

Understand Hono's key generic types:

### Env

The environment type containing Bindings and Variables:

```typescript theme={null}
export type Env = {
  Bindings?: Bindings
  Variables?: Variables
}
```

### Handler

The handler function type:

```typescript theme={null}
export type Handler<
  E extends Env = any,
  P extends string = any,
  I extends Input = BlankInput,
  R extends HandlerResponse<any> = any,
> = (c: Context<E, P, I>, next: Next) => R
```

### MiddlewareHandler

The middleware function type:

```typescript theme={null}
export type MiddlewareHandler<
  E extends Env = any,
  P extends string = string,
  I extends Input = {},
  R extends HandlerResponse<any> = Response,
> = (c: Context<E, P, I>, next: Next) => Promise<R | void>
```

## Custom Middleware Types

Create type-safe custom middleware:

```typescript theme={null}
import { MiddlewareHandler } from 'hono/types'

type MyEnv = {
  Variables: {
    userId: string
  }
}

const authMiddleware: MiddlewareHandler<MyEnv> = async (c, next) => {
  const token = c.req.header('Authorization')
  
  if (!token) {
    return c.text('Unauthorized', 401)
  }
  
  const userId = await verifyToken(token)
  c.set('userId', userId) // type-checked!
  
  await next()
}

app.use('*', authMiddleware)

app.get('/me', (c) => {
  const userId = c.get('userId') // typed as string
  return c.json({ userId })
})
```

## Response Types

Type your JSON responses:

```typescript theme={null}
type Post = {
  id: string
  title: string
  body: string
  createdAt: Date
}

app.get('/posts/:id', async (c) => {
  const post = await db.getPost(c.req.param('id'))
  return c.json<Post>(post) // Response typed as Post
})
```

## Context Types

Import and use Context types in your code:

```typescript theme={null}
import { Context } from 'hono'

type Env = {
  Variables: {
    user: User
  }
}

async function getCurrentUser(c: Context<Env>): Promise<User> {
  return c.get('user')
}

app.get('/profile', async (c) => {
  const user = await getCurrentUser(c)
  return c.json(user)
})
```

## Type Utilities

Hono provides type utilities for common patterns:

```typescript theme={null}
import type { 
  Input,
  BlankInput,
  BlankSchema,
  BlankEnv,
} from 'hono/types'
```

## Module Augmentation

Extend Hono's types using module augmentation:

```typescript theme={null}
declare module 'hono' {
  interface ContextVariableMap {
    user: User
    requestId: string
  }
}

// Now these are available globally
app.get('/any-route', (c) => {
  const user = c.get('user') // typed!
  const requestId = c.get('requestId') // typed!
  return c.json({ user, requestId })
})
```

## RPC Type Safety

Get end-to-end type safety with Hono's RPC client:

```typescript theme={null}
// server.ts
import { Hono } from 'hono'

const app = new Hono()
  .get('/posts/:id', (c) => {
    const id = c.req.param('id')
    return c.json({ id, title: 'Post Title' })
  })
  .post('/posts', async (c) => {
    const body = await c.req.json<{ title: string }>()
    return c.json({ id: '123', ...body }, 201)
  })

export type AppType = typeof app

// client.ts
import { hc } from 'hono/client'
import type { AppType } from './server'

const client = hc<AppType>('http://localhost:3000')

const res = await client.posts[':id'].$get({
  param: { id: '123' }
})
const data = await res.json() // fully typed!
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use type instead of interface for Env">
    Always use `type` to define your environment generics, not `interface`.
  </Accordion>

  <Accordion title="Define types at the app level">
    Define your environment types once when creating the Hono instance.
  </Accordion>

  <Accordion title="Leverage type inference">
    Let TypeScript infer types where possible instead of explicit annotations.
  </Accordion>

  <Accordion title="Use validation libraries with good types">
    Use Zod, Valibot, or similar libraries that provide excellent type inference.
  </Accordion>

  <Accordion title="Export your app type for RPC">
    Export your app type to enable type-safe RPC clients.
  </Accordion>
</AccordionGroup>

## Related

* [Validation](/guides/validation) - Type-safe validation patterns
* [Testing](/guides/testing) - Test with full type safety
* [Error Handling](/guides/error-handling) - Type-safe error handling
