TypeScript + Node.js 实战

TypeScript 在 Node.js 后端开发中广泛应用,本教程介绍 Node.js 项目的 TypeScript 配置和使用。

使用 TypeScript 可以让 Node.js 代码更安全、更易维护,特别适合中大型后端项目。

Node.js 教程查看:https://www.runoob.com/nodejs/nodejs-tutorial.html


Node.js + TypeScript 项目结构 项目配置 package.json tsconfig.json ts-node 源代码 (src/) types/ - 类型定义 services/ - 业务逻辑 routes/ - 路由处理 编译输出 (dist/) .js - JavaScript .d.ts - 类型声明 .map - 源码映射 Node.js 运行时 执行 JS 开发流程 npm install 安装依赖 tsc 编译 TypeScript node 运行 JavaScript API 请求测试

为什么需要在 Node.js 中使用 TypeScript

Node.js 项目通常涉及复杂的业务逻辑和数据处理,代码行数会快速增长。

使用 TypeScript 可以:提供编译期类型检查,减少运行时错误;利用 IDE 智能提示,提高开发效率;代码更易读和维护。

许多大型 Node.js 项目(如NestJS)都推荐或默认使用 TypeScript。

优势:TypeScript 的静态类型检查可以在开发时发现潜在问题,比运行时调试更高效。


项目初始化

首先初始化 Node.js 项目并安装 TypeScript 相关依赖。

初始化项目

# 初始化 npm
npm init -y

# 安装 TypeScript 和 Node.js 类型定义
# -D 表示安装为开发依赖
npm install -D typescript @types/node ts-node nodemon

# 初始化 tsconfig.json
npx tsc --init

说明:@types/node 提供了 Node.js API 的类型定义,ts-node 可以直接运行 TypeScript 文件,nodemon 监听文件变化自动重启。


tsconfig.json 配置

配置 TypeScript 编译器选项,针对 Node.js 项目进行优化。

tsconfig.json

{
    "compilerOptions": {
        // 编译目标:ES2020
        "target": "ES2020",

        // 模块系统:CommonJS(Node.js 原生支持)
        "module": "commonjs",

        // 启用的库
        "lib": ["ES2020"],

        // 输出目录
        "outDir": "./dist",

        // 源码根目录
        "rootDir": "./src",

        // 严格模式(始终开启)
        "strict": true,

        // ES 模块互操作
        "esModuleInterop": true,

        // 跳过库检查
        "skipLibCheck": true,

        // 强制文件名大小写一致
        "forceConsistentCasingInFileNames": true,

        // 模块解析策略
        "moduleResolution": "node",

        // 生成声明文件
        "declaration": true
    },
    // 要编译的文件
    "include": ["src/**/*"],
    // 排除的文件
    "exclude": ["node_modules", "dist"]
}

推荐配置:Node.js 项目推荐使用 module: "commonjs",这是 Node.js 原生支持的模块系统。


定义类型

在 types 目录中定义项目的类型接口。

src/types/index.ts

// 用户类型定义
export interface User {
    id: number;         // 用户 ID
    name: string;       // 用户名
    email: string;      // 邮箱
    createdAt: Date;   // 创建时间
}

// 创建用户的数据传输对象
export interface CreateUserDTO {
    name: string;       // 用户名(必填)
    email: string;     // 邮箱(必填)
    password: string;   // 密码(必填)
}

// API 响应类型(泛型)
export interface ApiResponse<T> {
    success: boolean;   // 是否成功
    data?: T;         // 成功时的数据
    error?: string;   // 失败时的错误信息
}

类型定义:将类型定义集中放在 types 目录,便于维护和复用。


实现服务

在 services 目录中实现业务逻辑,使用定义好的类型。

src/services/userService.ts

// 导入类型定义
import { User, CreateUserDTO, ApiResponse } from "../types";

// 用户服务类
class UserService {
    // 用户列表(内存存储)
    private users: User[] = [];
    // 下一个用户 ID
    private nextId = 1;

    // 创建用户
    createUser(dto: CreateUserDTO): ApiResponse<User> {
        try {
            // 创建用户对象
            const user: User = {
                id: this.nextId++,
                name: dto.name,
                email: dto.email,
                createdAt: new Date()
            };
            this.users.push(user);
            return { success: true, data: user };
        } catch (error) {
            return { success: false, error: "创建用户失败" };
        }
    }

    // 获取单个用户
    getUser(id: number): ApiResponse<User> {
        const user = this.users.find(u => u.id === id);
        if (!user) {
            return { success: false, error: "用户不存在" };
        }
        return { success: true, data: user };
    }

    // 获取所有用户
    getAllUsers(): ApiResponse<User[]> {
        return { success: true, data: this.users };
    }
}

// 导出单例
export default new UserService();

运行结果:

UserService 实例化成功

服务层:业务逻辑集中在 service 层,便于测试和复用。


创建 API 路由

使用 Express 框架创建 RESTful API。

src/index.ts

import express, { Request, Response } from "express";
import userService from "./services/userService";

// 创建 Express 应用
const app = express();
// 解析 JSON 请求体
app.use(express.json());

// 获取所有用户
app.get("/api/users", (req: Request, res: Response) => {
    const result = userService.getAllUsers();
    res.json(result);
});

// 获取单个用户
app.get("/api/users/:id", (req: Request, res: Response) => {
    const id = parseInt(req.params.id);
    const result = userService.getUser(id);
    res.json(result);
});

// 创建用户
app.post("/api/users", (req: Request, res: Response) => {
    const result = userService.createUser(req.body);
    res.json(result);
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
});

运行结果:

服务器运行在 http://localhost:3000

类型提示:使用 RequestResponse 类型,IDE 会提供完整的属性提示。


package.json 脚本

配置 npm 脚本,简化开发流程。

package.json

{
    "scripts": {
        // 编译 TypeScript
        "build": "tsc",

        // 运行编译后的 JavaScript
        "start": "node dist/index.js",

        // 开发模式:使用 nodemon 监听变化自动重启
        "dev": "nodemon --exec ts-node src/index.ts",

        // 运行测试
        "test": "jest"
    }
}

开发效率:使用 npm run dev 可以实现代码修改后自动重启服务器。


注意事项

  • 严格模式:始终启用 strict: true
  • 模块选择:Node.js 项目使用 commonjs
  • 类型定义:安装 @types/node 获取 API 类型
  • 开发工具:使用 ts-node 实现热重载

最佳实践:保持类型定义和业务逻辑分离,便于测试和维护。


总结

TypeScript 是 Node.js 后端开发的优秀选择。

  • 项目配置:使用 tsconfig.json 配置编译选项
  • 类型定义:在 types 目录集中管理接口
  • 服务层:业务逻辑与路由分离
  • 路由:使用 Express 创建 RESTful API
  • 开发工具:ts-node、nodemon 提高开发效率

建议:新项目直接使用 TypeScript,老项目可以逐步迁移。