req
), the response object (res
), and the next middleware function in the application’s request - response cycle. They can be used for tasks such as logging, authentication, and error handling.mkdir express-ts-app
cd express-ts-app
npm init -y
npm install express
npm install --save-dev typescript @types/node @types/express ts-node-dev
express
is the Express.js framework.typescript
is the TypeScript compiler.@types/node
and @types/express
are type definition files for Node.js and Express.js respectively.ts-node-dev
is a tool that allows you to run TypeScript files directly without having to compile them first.tsconfig.json
file:npx tsc --init
tsconfig.json
file to suit your needs. A basic configuration might look like this:{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
src
directory and an app.ts
file inside it:mkdir src
touch src/app.ts
import express from 'express';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
package.json
to start the application:{
"scripts": {
"start": "ts-node-dev src/app.ts"
}
}
npm start
You can create separate route files to organize your code better. For example, create a src/routes/userRoutes.ts
file:
import express from 'express';
const router = express.Router();
router.get('/', (req, res) => {
res.send('Get all users');
});
router.post('/', (req, res) => {
res.send('Create a new user');
});
export default router;
Then, import and use the router in your app.ts
file:
import express from 'express';
import userRoutes from './routes/userRoutes';
const app = express();
const port = 3000;
app.use(express.json());
app.use('/users', userRoutes);
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Middleware functions can be used to perform tasks such as logging or authentication. Here is an example of a simple logging middleware:
import express from 'express';
const app = express();
const port = 3000;
const logger = (req, res, next) => {
console.log(`Received ${req.method} request to ${req.url}`);
next();
};
app.use(logger);
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Error handling in Express.js with TypeScript can be done using middleware functions. Here is an example of a basic error - handling middleware:
import express, { Request, Response, NextFunction } from 'express';
const app = express();
const port = 3000;
app.get('/error', (req, res, next) => {
const error = new Error('Something went wrong');
next(error);
});
const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err);
res.status(500).send('Internal Server Error');
};
app.use(errorHandler);
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
import express, { Request, Response } from 'express';
interface User {
name: string;
age: number;
}
const app = express();
const port = 3000;
app.post('/users', (req: Request<{}, {}, User>, res: Response) => {
const user: User = req.body;
// Do something with the user
res.send('User created');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Using TypeScript with Express.js offers numerous benefits, including improved code quality, better maintainability, and early error detection. By following the fundamental concepts, usage methods, common practices, and best practices outlined in this blog post, you can build robust and scalable web applications and APIs. Whether you are a beginner or an experienced developer, combining TypeScript and Express.js is a great choice for your next project.