Зачем TypeScript в Node.js
▸Преимущества
Установка
1npm install -D typescript @types/node ts-node2npx tsc --init
tsconfig.json
▸Базовая конфигурация
1{2 "compilerOptions": {3 "target": "ES2020",4 "module": "commonjs",5 "lib": ["ES2020"],6 "outDir": "./dist",7 "rootDir": "./src",8 "strict": true,9 "esModuleInterop": true,10 "skipLibCheck": true,11 "forceConsistentCasingInFileNames": true,12 "resolveJsonModule": true,13 "declaration": true,14 "declarationMap": true,15 "sourceMap": true16 },17 "include": ["src/**/*"],18 "exclude": ["node_modules", "dist"]19}
▸Strict mode
1{2 "compilerOptions": {3 "strict": true4 }5}
Включает: strictNullChecks, strictFunctionTypes, strictBindCallApply, noImplicitAny, noImplicitThis.
Типизация
▸Типы и интерфейсы
1interface User {2 id: number;3 name: string;4 email: string;5 role: 'admin' | 'user';6}78type CreateUserDTO = Omit<User, 'id'>;
▸Enum
1enum Status {2 Active = 'ACTIVE',3 Inactive = 'INACTIVE',4 Deleted = 'DELETED',5}
▸Generics
1function identity<T>(arg: T): T {2 return arg;3}45interface ApiResponse<T> {6 data: T;7 status: number;8 message: string;9}
Express с TypeScript
1import express, { Request, Response, NextFunction } from 'express';23const app = express();45app.get('/users/:id', (req: Request<{ id: string }>, res: Response) => {6 const { id } = req.params;7 res.json({ id: parseInt(id) });8});910app.post('/users', (req: Request<{}, {}, CreateUserDTO>, res: Response) => {11 const user = req.body;12 // user типизирован13});1415// Middleware с типами16interface AppError extends Error {17 statusCode: number;18}1920function errorHandler(err: AppError, req: Request, res: Response, next: NextFunction) {21 res.status(err.statusCode || 500).json({ error: err.message });22}
Path aliases
▸Конфигурация
1{2 "compilerOptions": {3 "baseUrl": ".",4 "paths": {5 "@/*": ["src/*"],6 "@config/*": ["src/config/*"],7 "@services/*": ["src/services/*"]8 }9 }10}
▸Использование
1import { db } from '@/config/database';2import { UserService } from '@/services/user.service';
Complied vs Transpiled
▸ts-node для разработки
1npx ts-node src/index.ts
▸Компиляция для прода
1npx tsc2node dist/index.js
▸tsx для быстрого запуска
1npm install -D tsx2npx tsx src/index.ts
Паттерны
▸Repository pattern
1interface UserRepository {2 findById(id: number): Promise<User | null>;3 create(data: CreateUserDTO): Promise<User>;4 update(id: number, data: Partial<User>): Promise<User>;5 delete(id: number): Promise<void>;6}78class PrismaUserRepository implements UserRepository {9 async findById(id: number): Promise<User | null> {10 return prisma.user.findUnique({ where: { id } });11 }12 // ...13}
▸Dependency Injection
1class UserService {2 constructor(private userRepo: UserRepository) {}34 async getUser(id: number): Promise<User | null> {5 return this.userRepo.findById(id);6 }7}
Best Practices
▸Используйте strict mode
Всегда включайте strict в tsconfig. Это ловит больше ошибок.
▸Не используйте any
1// Плохо2function process(data: any): any { }34// Хорошо5function process(data: User): Response { }
▸Используйте type guards
1function isUser(obj: any): obj is User {2 return obj && typeof obj.id === 'number' && typeof obj.name === 'string';3}
Заключение
TypeScript делает Node.js-приложения надёжнее. Используйте strict mode, избегайте any и создавайте интерфейсы для всех данных. TypeScript — это инвестиция в качество кода.