JavaRush /Курсы /Модуль 2: Fullstack /Работа с Express и TypeScript

Работа с Express и TypeScript

Модуль 2: Fullstack
8 уровень , 1 лекция
Открыта

2.1 Установка и настройка проекта

Express — это минималистичный и гибкий фреймворк для создания веб-приложений на Node.js. TypeScript, в свою очередь, добавляет строгую типизацию и современные возможности языка, что позволяет улучшить разработку серверных приложений с Express. Ниже мы рассмотрим, как настроить проект с Express и TypeScript, и как создать и типизировать маршруты.

Установка и настройка проекта

1. Создание нового проекта

Создайте новую папку для проекта и инициализируйте npm:

Terminal
    
      mkdir my-express-app
    
  
    
      cd my-express-app
    
  
    
      npm init -y
    
  

2. Установка необходимых зависимостей

Установите Express и необходимые типы для него, а также TypeScript и другие инструменты:

Terminal
    
      npm install express
    
  
    
      npm install @types/express @types/node typescript ts-node-dev --save-dev
    
  

Где:

  • express: основной пакет Express
  • @types/express: типы для Express
  • @types/node: типы для Node.js
  • typescript: компилятор TypeScript
  • ts-node-dev: инструмент для запуска и перезапуска TypeScript приложений при изменениях кода

3. Создание конфигурационного файла tsconfig.json

Создайте файл tsconfig.json в корне проекта.

Пример tsconfig.json:

JSON
    
      {
        "compilerOptions": {
          "target": "ES6",
          "module": "commonjs",
          "outDir": "./dist",
          "rootDir": "./src",
          "strict": true,
          "esModuleInterop": true,
          "skipLibCheck": true
        },
        "include": ["src"],
        "exclude": ["node_modules"]
      }
    
  

4. Создание структуры проекта

Создайте папку src для исходного кода и файл src/index.ts:

Terminal
    
      mkdir src
    
  
    
      touch src/index.ts
    
  

2.2 Создание и настройка сервера

1. Создание базового сервера

Пример src/index.ts:

TypeScript
    
      import express, { Request, Response } from 'express';

      const app = express();
      const port = 3000;

      app.get('/', (req: Request, res: Response) => {
        res.send('Hello, Express with TypeScript!');
      });

      app.listen(port, () => {
        console.log(`Server is running at http://localhost:${port}`);
      });
    
  

В этом примере мы создаем простой сервер Express с одним маршрутом, который отвечает строкой "Hello, Express with TypeScript!".

2. Добавление скриптов для запуска

Добавьте скрипты в package.json для удобного запуска и разработки проекта.

Пример package.json:

JSON
    
      {
        "name": "my-express-app",
        "version": "1.0.0",
        "scripts": {
          "start": "ts-node-dev src/index.ts"
        },
        "dependencies": {
          "express": "^4.17.1"
        },
        "devDependencies": {
          "@types/express": "^4.17.11",
          "@types/node": "^14.14.31",
          "ts-node-dev": "^1.1.1",
          "typescript": "^4.1.3"
        }
      }
    
  

Запустите сервер с помощью команды:

Terminal
    
      npm start
    
  

2.3 Типизация маршрутов

Типизация маршрутов в Express помогает улучшить автодополнение и проверку типов в редакторах кода.

1. Типизация запросов и ответов

Express использует объекты Request и Response для обработки HTTP-запросов и ответов. Эти объекты можно типизировать с помощью типов из пакета @types/express.

Пример типизированного маршрута:

TypeScript
    
      app.get('/user/:id', (req: Request<{ id: string }>, res: Response) => {
        const userId = req.params.id;
        res.send(`User ID: ${userId}`);
      });
    
  

В этом примере мы типизируем параметры маршрута user/:id, указывая, что параметр id является строкой.

2. Типизация тела запроса

Для обработки POST-запросов и типизации тела запроса можно использовать интерфейсы TypeScript.

Пример типизированного POST-маршрута:

TypeScript
    
      app.use(express.json());

      interface User {
        name: string;
        age: number;
      }

      app.post('/user', (req: Request<{}, {}, User>, res: Response) => {
        const user = req.body;
        res.send(`User name: ${user.name}, age: ${user.age}`);
      });
    
  

В этом примере мы типизируем тело запроса, ожидая объект типа User.

2.4 Организация маршрутов

Для лучшей организации кода и маршрутов можно использовать роутеры Express. Создадим отдельные файлы для маршрутов и подключим их к основному приложению.

1. Создание роутера

Пример src/routes/userRoutes.ts:

TypeScript
    
      import { Router, Request, Response } from 'express';

      const router = Router();

      router.get('/:id', (req: Request<{ id: string }>, res: Response) => {
        const userId = req.params.id;
        res.send(`User ID: ${userId}`);
      });

      router.post('/', (req: Request<{}, {}, { name: string; age: number }>, res: Response) => {
        const user = req.body;
        res.send(`User name: ${user.name}, age: ${user.age}`);
      });

      export default router;
    
  

2. Подключение роутера к основному приложению

Пример src/index.ts:

TypeScript
    
      import express from 'express';
      import userRoutes from './routes/userRoutes';

      const app = express();
      const port = 3000;

      app.use(express.json());
      app.use('/user', userRoutes);

      app.get('/', (req, res) => {
        res.send('Hello, Express with TypeScript!');
      });

      app.listen(port, () => {
        console.log(`Server is running at http://localhost:${port}`);
      });
    
  

В этом примере мы создаем отдельный роутер для маршрутов, связанных с пользователями, и подключаем его к основному приложению.

2.5 Обработка ошибок

Обработка ошибок в Express осуществляется с помощью промежуточных обработчиков (middleware).

Пример обработки ошибок:

TypeScript
    
      app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
        console.error(err.message);
        res.status(500).send('Internal Server Error');
      });
    
  

Типизация ошибки и промежуточных обработчиков помогает избежать ошибок при обработке исключений.

Пример проекта

Давайте соберем все части вместе и создадим полный пример проекта с Express и TypeScript.

Структура проекта:

Text
    
      my-express-app/
      ├── node_modules/
      ├── src/
      │   ├── routes/
      │   │   └── userRoutes.ts
      │   └── index.ts
      ├── tsconfig.json
      └── package.json
    
  

src/routes/userRoutes.ts:

TypeScript
    
      import { Router, Request, Response } from 'express';

      const router = Router();

      router.get('/:id', (req: Request<{ id: string }>, res: Response) => {
        const userId = req.params.id;
        res.send(`User ID: ${userId}`);
      });

      router.post('/', (req: Request<{}, {}, { name: string; age: number }>, res: Response) => {
        const user = req.body;
        res.send(`User name: ${user.name}, age: ${user.age}`);
      });

      export default router;
    
  

src/routes/userRoutes.ts:

TypeScript
    
      import { Router, Request, Response } from 'express';

      const router = Router();

      router.get('/:id', (req: Request<{ id: string }>, res: Response) => {
        const userId = req.params.id;
        res.send(`User ID: ${userId}`);
      });

      router.post('/', (req: Request<{}, {}, { name: string; age: number }>, res: Response) => {
        const user = req.body;
        res.send(`User name: ${user.name}, age: ${user.age}`);
      });

      export default router;
    
  

src/index.ts:

TypeScript
    
      import express from 'express';
      import userRoutes from './routes/userRoutes';

      const app = express();
      const port = 3000;

      app.use(express.json());
      app.use('/user', userRoutes);

      app.get('/', (req, res) => {
        res.send('Hello, Express with TypeScript!');
      });

      app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
        console.error(err.message);
        res.status(500).send('Internal Server Error');
      });

      app.listen(port, () => {
        console.log(`Server is running at http://localhost:${port}`);
      });
    
  
3
Задача
Модуль 2: Fullstack, 8 уровень, 1 лекция
Недоступна
Создание базового Express сервера
Создание базового Express сервера
3
Задача
Модуль 2: Fullstack, 8 уровень, 1 лекция
Недоступна
Типизация параметров запроса
Типизация параметров запроса
3
Задача
Модуль 2: Fullstack, 8 уровень, 1 лекция
Недоступна
Типизация POST запроса
Типизация POST запроса
3
Задача
Модуль 2: Fullstack, 8 уровень, 1 лекция
Недоступна
Обработка ошибок в Express
Обработка ошибок в Express
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Антон Уровень 90
23 января 2025
Чтобы не возникала ошибка при добавлении аннотации @PrimaryGeneratedColumn() error TS1240: Unable to resolve signature of property decorator when called as an expression. Argument of type 'undefined' is not assignable to parameter of type 'Object' - нужно добавить в tsconfig.json в compilerOptions - experimentalDecorators": true и "emitDecoratorMetadata": true