DEV Community

Владимир Кудрявченко
Владимир Кудрявченко

Posted on • Originally published at dev.to

Научно-технический блог | TypeScript ускоряет разработку масштабируемых, типобезопасных back-end систем.

Introduction

TypeScript has rapidly become a cornerstone of modern backend development, combining the power of static typing with the flexibility of JavaScript. Its ability to catch errors at compile time, improve code maintainability, and scale large applications makes it an ideal choice for backend systems. Paired with frameworks like Node.js and Express, TypeScript enables developers to build robust, type-safe APIs and microservices.

This article walks you through the essentials of setting up a TypeScript backend, from environment configuration to deploying a production-ready application. Whether you're transitioning from JavaScript or starting fresh, this guide provides actionable steps to kickstart your project.

Setting Up the Development Environment

Before diving into code, ensure your machine has the necessary tools:

Node.js and npm: Install the latest LTS version from nodejs.org. TypeScript: Install globally via npm:

npm install -g typescript Enter fullscreen mode Exit fullscreen mode

ts-node: Enables running TypeScript directly without precompiling:

npm install -g ts-node Enter fullscreen mode Exit fullscreen mode

Type Definitions: Install Node.js type definitions for autocompletion and linting:

npm install --save-dev @types/node Enter fullscreen mode Exit fullscreen mode

Initialize a Project

mkdir my-ts-backend cd my-ts-backend npm init -y npm install express npm install --save-dev typescript ts-node @types/express Enter fullscreen mode Exit fullscreen mode

Create a tsconfig.json file to configure TypeScript:

npx tsc --init Enter fullscreen mode Exit fullscreen mode

Edit tsconfig.json to match backend needs:

{ "target" : "ES2020" , "module" : "CommonJS" , "outDir" : "./dist" , "strict" : true , "esModuleInterop" : true , "skipLibCheck" : true } Enter fullscreen mode Exit fullscreen mode

Project Structure

A well-organized structure ensures scalability. Adopt this common layout:

src/ ├── controllers/ # Handle HTTP requests ├── services/ # Business logic ├── routes/ # API endpoint mappings ├── middleware/ # Custom middleware (e.g., auth) ├── models/ # Database models ├── config/ # Configuration files ├── utils/ # Helper functions ├── index.ts # Entry point .env # Environment variables package.json tsconfig.json Enter fullscreen mode Exit fullscreen mode

Creating a Basic Server with Express

Start with a minimal Express server in src/index.ts :

import express , { Express , Request , Response } from ' express ' ; const app : Express = express (); const PORT = process . env . PORT || 3000 ; app . get ( ' / ' , ( req : Request , res : Response ) => { res . status ( 200 ). json ({ message : ' Hello from TypeScript! ' }); }); app . listen ( PORT , () => { console . log ( Server running at http://localhost: ${ PORT } ); }); Enter fullscreen mode Exit fullscreen mode

Run the server with:

npx ts-node src/index.ts Enter fullscreen mode Exit fullscreen mode

Implementing Business Logic and Middleware

Controllers and Services

Separate concerns by splitting request handling (controllers) from business logic (services).

Example Controller ( src/controllers/userController.ts ):

import { Request , Response } from ' express ' ; import { UserService } from ' ../services/userService ' ; export class UserController { private userService : UserService ; constructor () { this . userService = new UserService (); } public getAllUsers = ( req : Request , res : Response ) => { const users = this . userService . fetchAll (); res . status ( 200 ). json ( users ); }; } Enter fullscreen mode Exit fullscreen mode

Service ( src/services/userService.ts ):

export class UserService { public fetchAll (): string [] { return [ ' Alice ' , ' Bob ' ]; // Mock data } } Enter fullscreen mode Exit fullscreen mode

Middleware

Create reusable middleware in src/middleware/loggingMiddleware.ts :

import { Request , Response , NextFunction } from ' express ' ; export const logger = ( req : Request , res : Response , next : NextFunction ) => { console . log ( [ ${ new Date (). toISOString ()} ] ${ req . method } ${ req . url } ); next (); }; Enter fullscreen mode Exit fullscreen mode

Apply it in index.ts :

app . use ( logger ); Enter fullscreen mode Exit fullscreen mode

Connecting to a Database

TypeScript works seamlessly with ORMs like TypeORM or Mongoose. Here's a Mongoose example:

Install dependencies:

npm install mongoose npm install --save-dev @types/mongoose Enter fullscreen mode Exit fullscreen mode

Define a Model ( src/models/User.ts ):

import { model , Schema } from ' mongoose ' ; interface User { name : string ; email : string ; } const UserSchema = new Schema < User > ({ name : { type : String , required : true }, email : { type : String , required : true , unique : true } }); export default model < User > ( ' User ' , UserSchema ); Enter fullscreen mode Exit fullscreen mode

Connect in index.ts :

import mongoose from ' mongoose ' ; mongoose . connect ( ' mongodb://localhost:27017/mydb ' ); Enter fullscreen mode Exit fullscreen mode

Environment Variables and Configuration

Use dotenv to manage environment variables:

Install:

npm install dotenv Enter fullscreen mode Exit fullscreen mode

Create .env :

PORT=4000 DB_URI=mongodb://localhost:27017/mydb Enter fullscreen mode Exit fullscreen mode

Access in src/config/index.ts :

import dotenv from ' dotenv ' ; dotenv . config (); export default { port : process . env . PORT , dbUri : process . env . DB_URI }; Enter fullscreen mode Exit fullscreen mode

Error Handling and Validation

Centralized Error Handling

Create an error middleware ( src/middleware/errorMiddleware.ts ):

import { NextFunction , Request , Response } from ' express ' ; import { AppError } from ' ../utils/appError ' ; export const errorHandler = ( err : AppError , req : Request , res : Response , next : NextFunction ) => { const statusCode = err . statusCode || 500 ; res . status ( statusCode ). json ({ status : ' error ' , message : err . message }); }; Enter fullscreen mode Exit fullscreen mode

Input Validation

Use zod for schema validation:

npm install zod Enter fullscreen mode Exit fullscreen mode

Example validation pipe ( src/utils/validate.ts ):

import { ZodSchema } from ' zod ' ; export const validate = ( schema : ZodSchema ) => ( payload : unknown ) => { return schema . parse ( payload ); }; Enter fullscreen mode Exit fullscreen mode

Testing the Backend

Use Jest and Supertest for testing:

Install:

npm install --save-dev jest supertest Enter fullscreen mode Exit fullscreen mode

Write a test ( tests/index.test.ts ):

import request from ' supertest ' ; import app from ' ../src/index ' ; describe ( ' GET / ' , () => { it ( ' returns a 200 status code ' , async () => { const response = await request ( app ). get ( ' / ' ); expect ( response . status ). toBe ( 200 ); }); }); Enter fullscreen mode Exit fullscreen mode

Run tests:

npm test Enter fullscreen mode Exit fullscreen mode

Deployment Considerations

Compile TypeScript:

npx tsc Enter fullscreen mode Exit fullscreen mode

Production Build:

The compiled JS files will be in /dist . Dockerize:

FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY dist/ . CMD ["node", "index.js"] Enter fullscreen mode Exit fullscreen mode

Deploy: Use platforms like Vercel, Heroku, or AWS with CI/CD pipelines.

Conclusion

TypeScript transforms backend development by enforcing type safety and reducing runtime errors. By following this guide, you've set up a scalable project structure, integrated Express and a database, and implemented best practices for error handling and testing.

Next steps:

Explore advanced TypeScript features (generics, decorators).

Implement authentication (JWT, OAuth).

Monitor performance with tools like Winston or Datadog.

With this foundation, you're equipped to build enterprise-grade backends that stand the test of time.

Science and Technology Blog | TypeScript speeds up the development of scalable, type-safe back-end systems.

Headline: TypeScript: A New Level of Backend Development

TypeScript is changing the game in backend development by combining static typing with JavaScript’s flexibility. It helps catch errors early and boost project scalability.


Научно-технический блог | TypeScript ускоряет разработку масштабируемых, типобезопасных back-end систем.

Заголовок: TypeScript: Новый уровень бэкенд-разработки

TypeScript меняет правила игры в backend-разработке, совмещая статическую типизацию и гибкость JavaScript. Он помогает предварительно ловить ошибки и повышать масштабируемость проектов.

Подробнее в ТГ: @DevPulseAI

backend

Top comments (0)