TypeScript Setup

Fastify-Typed Routes With Generics

TypeScript Setup

Fastify ships first-class TypeScript types; route generics give you typed body, params, query, and reply with zero extra build steps.

4 min read Level 2/5 #fastify#typescript#generics
What you'll learn
  • Install Node and Fastify type packages
  • Use route generics for typed inputs
  • Pair with TypeBox or zod for runtime types

Fastify is written in TypeScript and exposes rich types. The default DX is good — adding a type provider makes it great.

Project Setup

npm i fastify
npm i -D typescript tsx @types/node
npx tsc --init --module nodenext --target es2022 --strict

Fastify 5 is ESM-first; set "type": "module" in package.json and use the nodenext module resolution in tsconfig.json.

Route Generics

type SearchQuery = { q: string; page?: number };
type SearchReply = { results: Array<{ id: number; title: string }> };

app.get<{ Querystring: SearchQuery; Reply: SearchReply }>(
  '/search',
  async (req) => {
    const q = req.query.q.trim();
    const page = req.query.page ?? 1;
    return { results: await search(q, page) };
  },
);

req.query, req.body, req.params, and the return type are all checked at compile time.

Type Providers

Hand-written generics drift from runtime schemas. A type provider derives types from your schema:

import { Type } from '@sinclair/typebox';
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox';

const typed = app.withTypeProvider<TypeBoxTypeProvider>();

typed.post('/users', {
  schema: {
    body: Type.Object({ email: Type.String({ format: 'email' }) }),
  },
  handler: async (req) => req.body.email.toLowerCase(),
});

One schema definition powers Ajv validation, OpenAPI docs, and compile-time types — covered in depth in the TypeBox lesson.

Schemas — Validate & Serialize →