TypeScript与Node.js #

一、Node.js项目配置 #

1.1 初始化项目 #

bash
npm init -y
npm install typescript @types/node --save-dev
npx tsc --init

1.2 tsconfig.json #

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

1.3 package.json #

json
{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts",
    "dev:watch": "ts-node-dev --respawn src/index.ts"
  }
}

二、Express类型 #

2.1 安装类型 #

bash
npm install express
npm install @types/express --save-dev

2.2 基本Express应用 #

typescript
import express, { Request, Response, NextFunction } from 'express';

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

app.use(express.json());

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

app.get('/users/:id', (req: Request<{ id: string }>, res: Response) => {
    const { id } = req.params;
    res.json({ id, name: 'User' });
});

app.post('/users', (req: Request, res: Response) => {
    const { name, email } = req.body;
    res.status(201).json({ id: 1, name, email });
});

app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
    console.error(err.stack);
    res.status(500).json({ error: 'Something went wrong!' });
});

app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

2.3 扩展Request类型 #

typescript
declare module 'express' {
    interface Request {
        user?: {
            id: string;
            name: string;
            role: string;
        };
    }
}

const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
    req.user = { id: '1', name: 'Alice', role: 'admin' };
    next();
};

app.use(authMiddleware);

app.get('/profile', (req: Request, res: Response) => {
    res.json(req.user);
});

三、类型安全的路由 #

3.1 路由定义 #

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

const router = Router();

interface User {
    id: number;
    name: string;
    email: string;
}

const users: User[] = [];

router.get('/users', (req: Request, res: Response<User[]>) => {
    res.json(users);
});

router.get('/users/:id', (req: Request<{ id: string }>, res: Response<User | { error: string }>) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (user) {
        res.json(user);
    } else {
        res.status(404).json({ error: 'User not found' });
    }
});

router.post('/users', (req: Request<{}, User, Omit<User, 'id'>>, res: Response<User>) => {
    const newUser: User = {
        id: users.length + 1,
        ...req.body
    };
    users.push(newUser);
    res.status(201).json(newUser);
});

export default router;

3.2 控制器类 #

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

class UserController {
    async getAll(req: Request, res: Response): Promise<void> {
        const users = await UserService.findAll();
        res.json(users);
    }
    
    async getById(req: Request<{ id: string }>, res: Response): Promise<void> {
        const user = await UserService.findById(parseInt(req.params.id));
        if (user) {
            res.json(user);
        } else {
            res.status(404).json({ error: 'User not found' });
        }
    }
    
    async create(req: Request, res: Response): Promise<void> {
        const user = await UserService.create(req.body);
        res.status(201).json(user);
    }
}

export default new UserController();

四、数据库类型 #

4.1 模型定义 #

typescript
interface User {
    id: number;
    name: string;
    email: string;
    password: string;
    createdAt: Date;
    updatedAt: Date;
}

interface CreateUserDTO {
    name: string;
    email: string;
    password: string;
}

interface UpdateUserDTO {
    name?: string;
    email?: string;
}

4.2 Repository模式 #

typescript
interface Repository<T> {
    findById(id: number): Promise<T | null>;
    findAll(): Promise<T[]>;
    create(data: Partial<T>): Promise<T>;
    update(id: number, data: Partial<T>): Promise<T | null>;
    delete(id: number): Promise<boolean>;
}

class UserRepository implements Repository<User> {
    async findById(id: number): Promise<User | null> {
        return null;
    }
    
    async findAll(): Promise<User[]> {
        return [];
    }
    
    async create(data: Partial<User>): Promise<User> {
        return {} as User;
    }
    
    async update(id: number, data: Partial<User>): Promise<User | null> {
        return null;
    }
    
    async delete(id: number): Promise<boolean> {
        return true;
    }
}

五、中间件类型 #

5.1 中间件定义 #

typescript
import { Request, Response, NextFunction } from 'express';

type Middleware = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;

const logger: Middleware = (req, res, next) => {
    console.log(`${req.method} ${req.path}`);
    next();
};

const errorHandler: Middleware = (err, req, res, next) => {
    console.error(err);
    res.status(500).json({ error: err.message });
};

5.2 认证中间件 #

typescript
interface AuthRequest extends Request {
    user?: {
        id: string;
        role: string;
    };
}

const authenticate = async (
    req: AuthRequest,
    res: Response,
    next: NextFunction
): Promise<void> => {
    const token = req.headers.authorization?.split(' ')[1];
    
    if (!token) {
        res.status(401).json({ error: 'Unauthorized' });
        return;
    }
    
    try {
        const decoded = verifyToken(token);
        req.user = decoded;
        next();
    } catch (error) {
        res.status(401).json({ error: 'Invalid token' });
    }
};

六、实用示例 #

6.1 API服务器 #

typescript
import express, { Application } from 'express';

class App {
    private app: Application;
    private port: number;
    
    constructor(port: number) {
        this.app = express();
        this.port = port;
        this.setupMiddleware();
        this.setupRoutes();
    }
    
    private setupMiddleware(): void {
        this.app.use(express.json());
        this.app.use(express.urlencoded({ extended: true }));
    }
    
    private setupRoutes(): void {
        this.app.use('/api/users', userRouter);
        this.app.use('/api/posts', postRouter);
    }
    
    public listen(): void {
        this.app.listen(this.port, () => {
            console.log(`Server running on port ${this.port}`);
        });
    }
}

const app = new App(3000);
app.listen();

七、总结 #

本章介绍了TypeScript与Node.js的结合:

Express类型 #

  1. Request和Response类型
  2. 扩展Request类型
  3. 中间件类型

最佳实践 #

  1. 使用接口定义数据模型
  2. 使用Repository模式
  3. 类型安全的路由定义
最后更新:2026-03-26