<h2>Configuração Inicial do Ambiente</h2>
<p>Antes de iniciar qualquer projeto com TypeScript e Node.js, você precisa configurar o ambiente corretamente. Comece instalando Node.js (versão 16+) e criando um novo diretório para seu projeto. Execute <code>npm init -y</code> e instale as dependências essenciais: TypeScript, Express e tipos do Node.</p>
<pre><code class="language-bash">npm install express cors dotenv
npm install -D typescript ts-node @types/express @types/node ts-node-dev
npx tsc --init</code></pre>
<p>O arquivo <code>tsconfig.json</code> gerado define como o TypeScript será compilado. Ajuste as configurações para ambiente Node.js modificando <code>target</code> para <code>"ES2020"</code> e <code>module</code> para <code>"commonjs"</code>. Em <code>compilerOptions</code>, adicione <code>"strict": true</code> para ativar verificações rigorosas de tipo — essencial para APIs robustas.</p>
<h2>Estrutura de Projeto e Tipagem</h2>
<p>Uma API bem organizada segue uma arquitetura clara com separação de responsabilidades. Crie a seguinte estrutura:</p>
<pre><code>src/
├── controllers/
├── routes/
├── models/
├── middleware/
└── index.ts</code></pre>
<p>Comece definindo seus tipos e interfaces. No arquivo <code>src/models/User.ts</code>, declare a estrutura esperada:</p>
<pre><code class="language-typescript">export interface User {
id: number;
name: string;
email: string;
createdAt: Date;
}
export type CreateUserDTO = Omit<User, 'id' | 'createdAt'>;</code></pre>
<p>Essa abordagem garante que toda comunicação de dados seja validada pelo TypeScript em tempo de desenvolvimento, evitando bugs em produção.</p>
<h2>Criando sua Primeira API REST Tipada</h2>
<p>Agora vamos construir uma API funcional do zero. No arquivo <code>src/index.ts</code>:</p>
<pre><code class="language-typescript">import express, { Express, Request, Response } from 'express';
import cors from 'cors';
const app: Express = express();
const PORT = process.env.PORT || 3000;
app.use(cors());
app.use(express.json());
// Simulando um banco de dados em memória
const users: User[] = [];
let nextId = 1;
app.get('/users', (req: Request, res: Response): void => {
res.json(users);
});
app.post('/users', (req: Request, res: Response): void => {
const { name, email }: CreateUserDTO = req.body;
if (!name || !email) {
res.status(400).json({ error: 'Name and email are required' });
return;
}
const newUser: User = {
id: nextId++,
name,
email,
createdAt: new Date()
};
users.push(newUser);
res.status(201).json(newUser);
});
app.get('/users/:id', (req: Request, res: Response): void => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
res.status(404).json({ error: 'User not found' });
return;
}
res.json(user);
});
app.listen(PORT, () => {
console.log(Servidor rodando em http://localhost:${PORT});
});</code></pre>
<p>Observe como cada rota possui tipos explícitos para <code>Request</code> e <code>Response</code>. Isso oferece autocompletar inteligente e previne erros de tipagem.</p>
<h2>Validação e Middleware Tipado</h2>
<p>Validação é crucial para APIs seguras. Crie um middleware tipado em <code>src/middleware/validateUser.ts</code>:</p>
<pre><code class="language-typescript">import { Request, Response, NextFunction } from 'express';
import { CreateUserDTO } from '../models/User';
export const validateUserData = (
req: Request,
res: Response,
next: NextFunction
): void => {
const { name, email } = req.body;
if (typeof name !== 'string' || name.trim().length === 0) {
res.status(400).json({ error: 'Invalid name' });
return;
}
if (typeof email !== 'string' || !email.includes('@')) {
res.status(400).json({ error: 'Invalid email' });
return;
}
next();
};</code></pre>
<p>Agora aplique o middleware na rota POST:</p>
<pre><code class="language-typescript">app.post('/users', validateUserData, (req: Request, res: Response): void => {
// seu código aqui
});</code></pre>
<p>Essa separação mantém o código limpo e reutilizável. TypeScript garante que você não esqueça de chamar <code>next()</code> ou que retorne valores inesperados.</p>
<h2>Tratamento de Erros e Tipos Avançados</h2>
<p>Para APIs profissionais, implemente um manipulador de erros centralizado. Crie <code>src/middleware/errorHandler.ts</code>:</p>
<pre><code class="language-typescript">import { Request, Response, NextFunction } from 'express';
export class ApiError extends Error {
constructor(
public statusCode: number,
message: string
) {
super(message);
this.name = 'ApiError';
}
}
export const errorHandler = (
err: Error,
req: Request,
res: Response,
next: NextFunction
): void => {
if (err instanceof ApiError) {
res.status(err.statusCode).json({ error: err.message });
return;
}
res.status(500).json({ error: 'Internal server error' });
};</code></pre>
<p>Use em seu <code>index.ts</code>:</p>
<pre><code class="language-typescript">app.use(errorHandler);</code></pre>
<p>Tipos genéricos também são poderosos. Para respostas padronizadas:</p>
<pre><code class="language-typescript">interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
}
const sendResponse = <T>(res: Response, statusCode: number, data: T): void => {
res.status(statusCode).json({ success: true, data });
};</code></pre>
<h2>Conclusão</h2>
<p>Você aprendeu que TypeScript transforma Node.js em uma plataforma robusta para APIs. Os três pontos principais são: <strong>(1) Tipagem explícita previne bugs antes do deploy</strong>, garantindo segurança em tempo de desenvolvimento; <strong>(2) Estrutura organizada com separação de responsabilidades</strong> (controllers, models, middleware) escala bem conforme seu projeto cresce; <strong>(3) Validação e tratamento de erros centralizados</strong> mantém o código consistente e profissional. Pratique esses conceitos construindo pequenas APIs e, progressivamente, explore bibliotecas como Zod para validação mais robusta e bancos de dados reais. O investimento inicial em tipagem rigorosa economiza horas de debugging futuramente.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.typescriptlang.org/docs/" target="_blank" rel="noopener noreferrer">TypeScript Official Documentation</a></li>
<li><a href="https://expressjs.com/" target="_blank" rel="noopener noreferrer">Express.js Guide</a></li>
<li><a href="https://github.com/goldbergyoni/nodebestpractices" target="_blank" rel="noopener noreferrer">Node.js Best Practices</a></li>
<li><a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook - Advanced Types</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/typescript-express-tutorial" target="_blank" rel="noopener noreferrer">Building REST APIs with Express and TypeScript</a></li>
</ul>