Core Concepts
Next-TS-API is built around several core concepts that work together to provide end-to-end type safety for your Next.js API routes.
Type Generation
Next-TS-API automatically generates TypeScript types for your API routes by analyzing your route handlers. This includes:
- Request body types
- Response payload types
- Query parameters
- Path parameters
The generated types are stored in types/next-ts-api.ts and are automatically updated when you make changes to your API routes.
Route Handlers
Route handlers in Next-TS-API are enhanced versions of Next.js route handlers with built-in type safety:
import { NextApiRequest } from 'next-ts-api';
// POST handler with typed request body
export async function POST(
request: NextApiRequest<{
title: string;
completed: boolean;
}>
) {
const { title, completed } = await request.json();
return Response.json({ success: true, data: { title, completed } });
}Type-Safe API Client
The API client provides type-safe access to your API routes:
import { createNextFetchApi } from "next-ts-api";
import { type ApiRoutes } from "../types/next-ts-api";
// Create a type-safe API client
export const api = createNextFetchApi<ApiRoutes>();
// All API calls are now type-safe
const response = await api('users', {
method: 'POST',
body: {
name: 'John', // Type checked!
email: 'john@example.com' // Type checked!
}
});File Uploads & Form Data
For multipart requests, declare the field shape on the handler just like a JSON
body, then read it with the typed request.formData():
// app/api/upload/route.ts
import { NextApiRequest } from 'next-ts-api';
import { NextResponse } from 'next/server';
export async function POST(
request: NextApiRequest<{ file: File; name: string }>
) {
const data = await request.formData();
const file = data.get('file');
const name = data.get('name');
if (!(file instanceof File)) {
return NextResponse.json({ error: 'file required' }, { status: 400 });
}
return NextResponse.json({ name, size: file.size });
}On the client, use form instead of body. The client builds the FormData
and sets the correct headers for you:
const response = await api('upload', {
method: 'POST',
form: {
file: new File(['hello'], 'hello.txt', { type: 'text/plain' }),
name: 'greeting', // Type checked against the handler!
},
});
const data = await response.json();Best Practices
-
Always Import from next-ts-api:
import { NextApiRequest } from 'next-ts-api'; // NOT from 'next/types' -
Use Type Annotations:
// Good - explicit types export async function POST( request: NextApiRequest<CreateTodoInput> ) { } // Avoid - implicit any export async function POST(request) { } -
Leverage Generated Types:
import { type ApiRoutes } from "../types/next-ts-api"; // Use throughout your application
Next Steps
- Check out the API Reference for detailed documentation
- See Examples for common usage patterns
- Learn about Contributing to Next-TS-API