Express Requests With TypeScript

A passionate beautiful and curious beaut from Africa, I can't wait to see what the world of programming has to offer
Express.js is a popular web application framework for Node.js, and when combined with TypeScript, it provides a robust and type-safe environment for building web applications. In this article, we'll explore how to handle requests in an Express application using TypeScript, focusing on type safety and best practices.
Setting Up the Project
First, let's set up a new Express project with TypeScript. We'll need to install the necessary dependencies:
mkdir express-typescript-demo
cd express-typescript-demo
npm init -y
npm install express @types/express typescript ts-node
npm install --save-dev @types/node
Next, let's create a tsconfig.json file for TypeScript configuration:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Creating a Basic Express Server
Let's start by creating a basic Express server with TypeScript. Create a file named src/app.ts:
import express, { Express, Request, Response } from 'express';
const app: Express = express();
const port = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, TypeScript Express!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
This sets up a basic Express server with a single route. To run it, add the following script to your package.json:
"scripts": {
"start": "ts-node src/app.ts"
}
Now you can start the server with npm start.
Handling Different Types of Requests
Express can handle various types of HTTP requests. Let's explore how to handle GET, POST, PUT, and DELETE requests with TypeScript.
GET Request
GET requests are used to retrieve data. Let's add a route that accepts query parameters:
app.get('/users', (req: Request, res: Response) => {
const { name, age } = req.query;
res.send(`User name: ${name}, age: ${age}`);
});
To improve type safety, we can create an interface for our query parameters:
interface UserQuery {
name?: string;
age?: string;
}
app.get('/users', (req: Request<{}, {}, {}, UserQuery>, res: Response) => {
const { name, age } = req.query;
res.send(`User name: ${name}, age: ${age}`);
});
POST Request
POST requests are typically used to submit data. Let's add a route that accepts JSON data:
app.use(express.json()); // Add this line to parse JSON bodies
interface User {
name: string;
age: number;
}
app.post('/users', (req: Request<{}, {}, User>, res: Response) => {
const { name, age } = req.body;
res.send(`Created user: ${name}, age: ${age}`);
});
PUT Request
PUT requests are used to update existing resources. Let's add a route that updates a user by ID:
interface UserParams {
id: string;
}
interface UserBody {
name?: string;
age?: number;
}
app.put('/users/:id', (req: Request<UserParams, {}, UserBody>, res: Response) => {
const { id } = req.params;
const { name, age } = req.body;
res.send(`Updated user ${id}: name: ${name}, age: ${age}`);
});
DELETE Request
DELETE requests are used to remove resources. Here's an example of a delete route:
app.delete('/users/:id', (req: Request<UserParams>, res: Response) => {
const { id } = req.params;
res.send(`Deleted user with id: ${id}`);
});
Error Handling
Proper error handling is crucial in Express applications. Let's add a simple error handler:
import { NextFunction } from 'express';
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
Middleware
Middleware functions are functions that have access to the request and response objects. Let's create a simple logging middleware:
const loggingMiddleware = (req: Request, res: Response, next: NextFunction) => {
console.log(`${new Date().toISOString()}: ${req.method} ${req.url}`);
next();
};
app.use(loggingMiddleware);
Conclusion
Using TypeScript with Express provides strong typing and better tooling support, helping to catch errors early and improve code quality. We've covered the basics of handling different types of requests, error handling, and middleware in an Express application with TypeScript.
Remember to always validate and sanitize input data, especially when working with user-submitted content. Additionally, consider using more robust validation libraries like Joi or class-validator for complex validation scenarios.
As you build more complex applications, you might want to explore additional topics such as:
Authentication and authorization
Database integration (e.g., with TypeORM or Prisma)
API documentation (e.g., with Swagger)
Testing (e.g., with Jest)
These topics will help you create more robust and maintainable Express applications with TypeScript.



