TypeBox
Import t from elysia to write schemas that validate values at runtime and infer their TypeScript types.
This reference covers primitive types, Elysia types, and Elysia’s conversion behavior.
Primitive type
Section titled “Primitive type”TypeBox schemas use familiar TypeScript names, such as String, Number, Boolean, and Object. It also provides Intersect, KeyOf, and Tuple for more complex types.
To validate a request body as a string, pass t.String() in the route’s schema before the handler.
import { Elysia, t } from 'elysia'
new Elysia() .post('/', { body: t.String() }, ({ body }) => `Hello ${body}`) .listen(3000)Elysia runs the handler when the body matches. Otherwise, it raises a validation error through the error lifecycle.
Basic type
Section titled “Basic type”| TypeBox | TypeScript |
|---|---|
t.String() | string |
t.Number() | number |
t.Boolean() | boolean |
t.Array(t.Number()) | number[] |
t.Object({ x: t.Number() }) | { x: number } |
t.Null() | null |
t.Literal(42) | 42 |
Elysia re-exports TypeBox types alongside its HTTP-specific types. See the TypeBox reference for the full API.
Attribute
Section titled “Attribute”Pass options to add validation constraints. These follow JSON Schema keywords.
import { t } from 'elysia'
// Accepts '[email protected]'t.String({ format: 'email' })
// Accepts numbers from 10 through 100t.Number({ minimum: 10, maximum: 100 })
// Accepts one through five numberst.Array(t.Number(), { minItems: 1, maxItems: 5})
// Accepts { x: 100, y: 200 }t.Object({ x: t.Number() }, { additionalProperties: true})See the JSON Schema validation specification for the individual keywords.
Honorable mentions
Section titled “Honorable mentions”These patterns help you combine schemas and make fields optional.
Use t.Union to accept any of the listed types. It can be used on its own or as a field in t.Object.
import { t } from 'elysia'
// TypeScript: string | number// Accepts 'Hello' or 123t.Union([ t.String(), t.Number()])Optional
Section titled “Optional”Wrap a field in t.Optional to allow it to be omitted.
import { t } from 'elysia'
// TypeScript: { x: number, y?: number }// Accepts { x: 123 }t.Object({ x: t.Number(), y: t.Optional(t.Number())})Partial
Section titled “Partial”Use t.Partial to make every field in an object optional.
import { t } from 'elysia'
// TypeScript: { x?: number, y?: number }// Accepts { y: 123 }t.Partial( t.Object({ x: t.Number(), y: t.Number() }))Elysia type
Section titled “Elysia type”Elysia adds types for HTTP data, including files, cookies, and values encoded as strings.
| Type | Accepts |
|---|---|
| UnionEnum | One of a list of literal values |
| File | A single file |
| Files | Files in a single field |
| Cookie | A cookie jar with validation and cookie options |
| Nullable | A matching value or null |
| MaybeEmpty | A matching value, null, or undefined |
| Form | A FormData response |
| Uint8Array | A Uint8Array or an ArrayBuffer to convert |
| ArrayBuffer | An ArrayBuffer |
| ObjectString | An object or a JSON object string |
| BooleanString | A boolean or its string representation |
| Numeric | A number or numeric string |
UnionEnum
Section titled “UnionEnum”Accept one of the listed values. Values can be strings, numbers, or null.
import { t } from 'elysia'
t.UnionEnum(['rapi', 'anis', 1, null])Validate a single uploaded file.
import { t } from 'elysia'
t.File()Restrict the file’s media type, such as image/png or image. An array accepts any of its listed types.
import { t } from 'elysia'
t.File({ type: ['image/png', 'image/jpeg'] })minSize
Section titled “minSize”Set the lower file-size bound in bytes or use a k or m suffix. The file size must be at least the bound.
import { t } from 'elysia'
t.File({ minSize: '1k' })maxSize
Section titled “maxSize”Set the upper file-size bound in bytes or use a k or m suffix. The file size must not exceed the bound.
import { t } from 'elysia'
t.File({ maxSize: '5m' })File unit suffix
Section titled “File unit suffix”| Suffix | Bytes |
|---|---|
k | 1,024 |
m | 1,048,576 |
Both size options accept a number or a string such as '512k'.
Use t.Files for files in one field. It supports the File options and array length constraints such as minItems and maxItems.
import { t } from 'elysia'
t.Files()Cookie
Section titled “Cookie”Describe a cookie jar with object properties and cookie configuration.
import { t } from 'elysia'
t.Cookie({ name: t.String()})See cookies for reading, writing, and signing cookie values.
secrets
Section titled “secrets”Pass secrets in the second argument to sign cookies. A string uses one key; an array supports key rotation.
import { t } from 'elysia'
t.Cookie({ name: t.String() }, { secrets: ['current-secret', 'previous-secret'], sign: ['name']})New cookies use the first secret, which must be a non-empty string. Replace the example secrets with private application secrets.
Nullable
Section titled “Nullable”Accept a matching value or null, but not undefined.
import { t } from 'elysia'
t.Nullable(t.String())MaybeEmpty
Section titled “MaybeEmpty”Accept a matching value, null, or undefined. An empty string is accepted only if the wrapped schema accepts it.
import { t } from 'elysia'
t.MaybeEmpty(t.String())Use t.Form to validate a FormData response returned by the form helper.
import { t } from 'elysia'
t.Form({ someValue: t.File()})Uint8Array
Section titled “Uint8Array”Accept an ArrayBuffer or Uint8Array and decode it to a Uint8Array. Pair it with the arrayBuffer body parser for binary uploads.
import { Elysia, t } from 'elysia'
new Elysia() .post('/upload', { parse: 'arrayBuffer', body: t.Uint8Array() }, ({ body }) => body.byteLength)The API spelling is t.Uint8Array(), not t.UInt8Array().
ArrayBuffer
Section titled “ArrayBuffer”Validate an ArrayBuffer without converting it to a typed array.
import { Elysia, t } from 'elysia'
new Elysia() .post('/upload', { parse: 'arrayBuffer', body: t.ArrayBuffer() }, ({ body }) => body.byteLength)ObjectString
Section titled “ObjectString”Accept an object or a JSON string that decodes to the specified object. This is useful in query strings, headers, and FormData fields.
import { t } from 'elysia'
// Accepts { name: 'Rapi' } or '{"name":"Rapi"}'t.ObjectString({ name: t.String()})BooleanString
Section titled “BooleanString”Accept a boolean or the strings 'true' and 'false', then decode the result to a boolean.
import { t } from 'elysia'
t.BooleanString()Numeric
Section titled “Numeric”Accept a number or numeric string, then decode the result to a number. This is useful for path parameters and query values.
import { t } from 'elysia'
t.Numeric({ minimum: 1, maximum: 100 })Numeric supports the same numeric constraints as t.Number.
Elysia behavior
Section titled “Elysia behavior”Elysia converts common string-based HTTP inputs before your handler runs. Creating a schema outside a route doesn’t apply these route conversions.
Optional request schema
Section titled “Optional request schema”You can wrap the entire request schema in t.Optional, as well as individual object fields. This also applies to body and header schemas.
import { Elysia, t } from 'elysia'
new Elysia() .get('/optional', { query: t.Optional( t.Object({ name: t.String() }) ) }, ({ query }) => query)/optional can omit the query entirely. When a non-empty query is provided, it must contain a string name.
Number to Numeric
Section titled “Number to Numeric”Elysia converts t.Number at the root and direct properties of string-based request schemas, such as params, query, and headers, to numeric conversion. It also converts a root numeric body, but a number inside a JSON body object stays a number.
import { Elysia, t } from 'elysia'
new Elysia() .post('/:id', { params: t.Object({ // The path string becomes a number id: t.Number() }), body: t.Object({ // JSON must contain a number, not a string id: t.Number() }) }, ({ params, body }) => ({ pathId: params.id, bodyId: body.id }))
// No route conversion heret.Number()For /42 with {"id": 10}, both handler values are numbers. A JSON body of {"id": "10"} fails validation.
Boolean to BooleanString
Section titled “Boolean to BooleanString”Boolean conversion follows the same rule as numeric conversion. Direct path, query, and header fields accept string booleans; a boolean inside a JSON object stays a boolean.
import { Elysia, t } from 'elysia'
new Elysia() .post('/:enabled', { params: t.Object({ // The path string becomes a boolean enabled: t.Boolean() }), body: t.Object({ // JSON must contain a boolean, not a string enabled: t.Boolean() }) }, ({ params, body }) => ({ pathEnabled: params.enabled, bodyEnabled: body.enabled }))
// No route conversion heret.Boolean()For /true with {"enabled": false}, the handler receives true and false. A JSON body of {"enabled": "false"} fails validation.