TypeScript is a programming language developed by Microsoft that builds on JavaScript by adding static type definitions. This means you can specify the type of variables, function parameters, and return types, enhancing code quality and catching errors at compile time rather than runtime. TypeScript is transpiled into JavaScript, making it compatible with all JavaScript environments.
You can install TypeScript globally via npm or yarn using the following command:
npm install -g typescript
yarn global add typescript
Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for building web and mobile applications. It provides a thin layer of fundamental web application features without obscuring Node.js features. Express.js simplifies the process of building server-side web applications and APIs.
Installation and Setup: You can install Express.js as a dependency in your project via npm or yarn:
npm install express
yarn add express
When setting up a TypeScript-Express project, it’s essential to establish a clear project structure. This typically includes directories for controllers, routes, middleware, and other necessary files. For example:
project/
├── src/
│ ├── controllers/
│ ├── routes/
│ ├── middleware/
│ ├── types.ts
│ └── server.ts
├── package.json
├── tsconfig.json
└── yarn.lock
Before starting development, you need to install dependencies such as TypeScript, Express.js, and other libraries required for your project. You can manage dependencies using npm or yarn and configure TypeScript compiler options in the tsconfig.json
file.
To create an Express server with TypeScript, you first import the necessary modules (express
and http
). Then, you define your Express application and set up routes to handle incoming HTTP requests. Middleware can also be added to intercept and process requests before they reach the route handler.
// server.ts
import express, { Request, Response } from 'express';
const app = express();
const PORT = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, World!');
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
import express, { Request, Response } from 'express';
: This line imports the Express framework and types for Request and Response objects from the Express module.const app = express();
: This creates an Express application instance.const PORT = 3000;
: Defines the port on which the server will listen for incoming requests.app.get('/')
: Defines a route for handling GET requests to the root URL '/'
.(req: Request, res: Response) => { ... }
: This is the route handler function, which takes a request (req
) and response (res
) object as arguments.res.send('Hello, World!');
: Sends the string 'Hello, World!'
as the response to the client when the root URL is accessed.app.listen(PORT, () => { ... });
: Starts the Express server on the specified port (PORT
). It also includes a callback function that logs a message to the console when the server starts successfully.After writing the server code, you compile the TypeScript code to JavaScript using the TypeScript compiler (tsc
). Then, you start the Express server using Node.js. You can automate this process with tools like nodemon
to watch for changes and restart the server automatically.
TypeScript allows you to define custom types and interfaces to enforce type safety in your code. This is particularly useful when dealing with complex data structures such as objects returned from APIs. By defining types, you can catch type-related errors early in the development process.
// types.ts
interface User {
id: number;
name: string;
email: string;
}
// server.ts
import { User } from './types';
app.get('/user/:id', (req: Request, res: Response) => {
const user: User = { id: 1, name: 'John', email: 'john@example.com' };
res.json(user);
});
interface User { ... }
: Defines a TypeScript interface named User
, specifying the structure of a user object with properties id
, name
, and email
.import { User } from './types';
: Imports the User
interface from the types.ts
file.app.get('/user/:id', (req: Request, res: Response) => { ... });
: Defines a route for handling GET requests to URLs like /user/:id
, where :id
is a route parameter representing the user’s ID.const user: User = { id: 1, name: 'John', email: 'john@example.com' };
: Creates a user object with the specified properties, adhering to the User
interface defined earlier.res.json(user);
: Sends the user object as JSON in the response.Middleware functions are an integral part of Express.js development, allowing you to perform tasks such as logging, authentication, and error handling. In TypeScript, you can define custom middleware functions and ensure type safety by specifying the correct types for the request, response, and next function.
// middleware.ts
import { Request, Response, NextFunction } from 'express';
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`${req.method} ${req.path}`);
next();
}
// server.ts
import { logger } from './middleware';
app.use(logger);
export function logger(req: Request, res: Response, next: NextFunction) { ... }
: Defines a middleware function named logger
. It takes three parameters: req
(request object), res
(response object), and next
(next function in the middleware chain).console.log(
${req.method} ${req.path});
: Logs the HTTP method (GET
, POST
, etc.) and request path to the console.next();
: Calls the next()
function to pass control to the next middleware function in the chain.import { logger } from './middleware';
: Imports the logger
middleware function from the middleware.ts
file.app.use(logger);
: Mounts the logger
middleware globally, so it will be executed for every incoming request.In this chapter, we covered the fundamentals of using TypeScript with Express.js for backend development. We explored TypeScript's type system, Express.js's routing and middleware features, and how to combine them to build robust web applications. Happy coding !❤️