Tipar Express com TypeScript:
Instale @types/express, configure Request e Response tipados, crie interfaces customizadas e domine a tipagem do Router. Tudo com exemplos práticos pra usar agora.
Por que isso é importante
Tipar Express com TypeScript:. Instale @types/express, configure Request e Response tipados, crie interfaces customizadas e domine a tipagem do Router. Tudo com exemplos práticos pra usar agora.
O Que Significa Tipar Express com TypeScript
Express foi escrito em JavaScript. Quando você usa num projeto TypeScript, o compilador não faz ideia do que é Request, Response ou NextFunction. Pra ele, tudo é any. Isso mata o autocomplete, mata a segurança de tipos e mata a confiança no código.
O pacote @types/express resolve isso. Ele traz as definições de tipo de toda a API do Express: rotas, middleware, request, response, application. Depois de instalar, seu editor já reconhece métodos como res.json(), req.params, req.query e todos os overloads corretos.
Mas instalar @types/express é só o primeiro passo. O poder de verdade vem quando você customiza esses tipos. Estender a interface Request pra incluir dados do seu domínio, tipar params e query com valores específicos, criar tipos pro Router. Galera que faz isso direito nunca mais sofre com aquele bug de 'cannot read property of undefined' num endpoint.
Como Configurar Express com TypeScript Passo a Passo
Vamos do zero. Cada passo te leva do JavaScript puro até um servidor Express completamente tipado.
Exemplos Práticos de Tipagem no Express
Código fala mais que teoria. Vamos ver cada cenário real de tipagem no Express.
Setup Inicial: Servidor Express Tipado
// src/server.ts
import express, { Application, Request, Response } from 'express';
const app: Application = express();
app.use(express.json());
app.get('/', (req: Request, res: Response) => {
res.json({ message: 'Server tipado rodando!' });
});
app.listen(3000, () => {
console.log('Rodando na porta 3000');
});
Tipando Params e Body com Generics
// Tipos do domínio
interface CreateUserBody {
name: string;
email: string;
password: string;
}
interface UserParams {
id: string;
}
// Handler com body tipado
app.post('/users',
(req: Request<{}, {}, CreateUserBody>, res: Response) => {
const { name, email, password } = req.body;
// name, email, password: tudo com autocomplete!
res.status(201).json({ name, email });
}
);
// Handler com params tipado
app.get('/users/:id',
(req: Request<UserParams>, res: Response) => {
const { id } = req.params; // id é string, certeza total
res.json({ userId: id });
}
);
Estendendo Request com Declaração Global
// src/@types/express/index.d.ts
import { JwtPayload } from 'jsonwebtoken';
declare global {
namespace Express {
interface Request {
userId?: string;
userRole?: 'admin' | 'user' | 'moderator';
tenantId?: string;
}
}
}
// Agora no handler:
app.get('/profile', (req: Request, res: Response) => {
const userId = req.userId; // string | undefined
const role = req.userRole; // 'admin' | 'user' | 'moderator' | undefined
if (!userId) {
return res.status(401).json({ error: 'Nao autenticado' });
}
res.json({ userId, role });
});
Router Tipado e Organizado
// src/routes/user.routes.ts
import { Router, Request, Response } from 'express';
interface UserBody {
name: string;
email: string;
}
const userRouter = Router();
userRouter.get('/', async (req: Request, res: Response) => {
const users = await findAllUsers();
res.json(users);
});
userRouter.post('/', async (req: Request<{}, {}, UserBody>, res: Response) => {
const { name, email } = req.body;
const user = await createUser({ name, email });
res.status(201).json(user);
});
export { userRouter };
// src/server.ts
import { userRouter } from './routes/user.routes';
app.use('/users', userRouter);
Tipando Response com Generics
// Tipo da resposta
interface ApiResponse<T> {
data: T;
message: string;
status: number;
}
interface User {
id: string;
name: string;
email: string;
}
// Response tipado com o body da resposta
app.get('/users/:id',
(req: Request<UserParams>, res: Response<ApiResponse<User>>) => {
const user: User = {
id: req.params.id,
name: 'Maria',
email: 'maria@email.com'
};
// res.json valida o formato da resposta!
res.json({
data: user,
message: 'Usuario encontrado',
status: 200
});
}
);
Percebe o padrão? Cada handler tem clareza total sobre o que recebe e o que retorna. O editor mostra autocomplete pra tudo. Se alguém muda um campo na interface, o compilador aponta cada lugar que precisa atualizar. Simples assim.
Erros Comuns ao Tipar Express
Armadilhas que pegam todo dev no início
Esquecer esModuleInterop no tsconfig: sem essa flag, import express from 'express' não funciona. Você precisa usar import * as express, que é feio e propenso a erro. Ative a flag e use o import normal.
Colocar o arquivo .d.ts no lugar errado: a declaração global de Request precisa estar num caminho que o TypeScript reconheça. Coloque em src/@types/express/index.d.ts e garanta que o tsconfig inclui essa pasta em typeRoots ou include.
Tipar req.body sem validar: tipagem não valida dados em runtime. O body pode vir com qualquer formato. Use uma lib de validação como Zod ou Joi junto com os tipos. TypeScript confia no que você declara, mas o cliente pode mandar qualquer coisa.
Ignorar o retorno de res.json(): quando você tipa Response com generics, o compilador checa o formato da resposta. Se você manda um campo errado, dá erro. Isso é ótimo pra manter contratos de API consistentes.
Usar any nos handlers por preguiça: cada any que você coloca é um bug esperando acontecer. Gaste 2 minutos criando a interface correta. Seu eu do futuro agradece.
Checklist de Tipagem Express
Leve Seu Express Tipado Pro Próximo Nível
Tipar Express é o primeiro passo pra ter um backend Node.js profissional. No CrazyStack, você constrói uma API completa com Express, TypeScript, Prisma e autenticação JWT do zero. Não é tutorial básico: é um SaaS real com testes, deploy e arquitetura limpa.
Se você quer sair do 'funciona no meu PC' e entregar código que roda em produção sem surpresas, esse é o caminho.
Continue lendo
Como Tipar Request e Response no Express com TypeScript
A estender Request, tipar body, params e query no Express com TypeScript.
Como Tipar Middleware no Express com TypeScript
Domine RequestHandler, error middleware e async middleware tipados no Express.
Como Criar API REST com Node.js e TypeScript
Construa uma API REST completa com Node.js e TypeScript do zero ao deploy.
Interface no TypeScript
Quando usar interface