TypeScript
Elysia has a first-class support for TypeScript out of the box.
Most of the time, you wouldn't need to add any TypeScript annotations manually.
Inference
Elysia infers the type of request and response based on the schema you provide.
import { Elysia, t } from 'elysia'
import { z } from 'zod'
const app = new Elysia()
.post('/user/:id', ({ body }) => body, {
body: t.Object({
id: t.String()
}),
query: z.object({
name: z.string()
})
})
Elysia can automatically infers type from schema like TypeBox and your favorite validation library like:
- Zod
- Valibot
- ArkType
- Effect Schema
- Yup
- Joi
Schema to Type
All of schema library supported by Elysia can be converted to TypeScript type.
import { Elysia, t } from 'elysia'
const User = t.Object({
id: t.String(),
name: t.String()
})
type User = typeof User['static']
Type Performance
Elysia is built with type inference performance in mind.
Before every release, we have a local benchmark to ensure that type inference is always snappy, fast, and doesn't blow up your IDE with "Type instantiation is excessively deep and possibly infinite" error.
Most of the time writing Elysia, you wouldn't encounter any type performance issue.
However, if you do, here are how to break down what's slowing down your type inference:
- Navigate to the root of your project and runs
tsc --generateTrace trace --noEmit --incremental false
This should generate a trace
folder in your project root.
- Open Perfetto UI and drag the
trace/trace.json
file
It should show you a flame graph like this
Then you can find a chunk that takes a long time to be evaluated, click on it and it should show you how long the inference take, and which file, and line number it is coming from.
This should help you to identify the bottleneck of your type inference.
Eden
If you are having a slow type inference issue when using Eden, you can try using a sub app of Elysia to isolate the type inference.
import { Elysia } from 'elysia'
import { plugin1, plugin2, plugin3 } from from './plugin'
const app = new Elysia()
.use([plugin1, plugin2, plugin3])
.listen(3000)
export type app = typeof app
// Export sub app
export type subApp = typeof plugin1
And on your frontend, you can import the sub app instead of the whole app.
import { treaty } from '@elysiajs/eden'
import type { subApp } from 'backend/src'
const api = treaty<subApp>('localhost:3000')
This should make your type inference faster it doesn't need to evaluate the whole app.
See Eden Treaty to learn more about Eden.