TypeScript入门(八)模块与命名空间:代码世界的"城市规划"

3 阅读18分钟

第8章 模块与命名空间:代码世界的"城市规划"

想象你正在建设一座现代化的智慧城市——模块(Modules) 是功能各异的城区,命名空间(Namespaces) 则是区内的街道网络。如果说前面章节教会了你建造房屋,那么这一章将教你如何规划整座城市!让我们一起掌握TypeScript的代码组织艺术,让大型项目保持井然有序。

8.1 ES模块系统——现代JavaScript的"标准交通网" 🚇

ES模块(ES Modules)是JavaScript官方的模块系统,就像城市的地铁网络一样,连接着各个功能区域。TypeScript对其提供了原生支持,让代码组织变得优雅而高效。

🏗️ 基础模块导入导出:构建代码的"交通枢纽"

// 📁 math.ts - 数学工具模块
/**
 * 加法运算函数
 * @param a 第一个数字
 * @param b 第二个数字
 * @returns 两数之和
 */
export function add(a: number, b: number): number {
    const result = a + b;
    console.log(`计算:${a} + ${b} = ${result}`);
    return result;
}

/**
 * 减法运算函数
 * @param a 被减数
 * @param b 减数
 * @returns 两数之差
 */
export function subtract(a: number, b: number): number {
    const result = a - b;
    console.log(`计算:${a} - ${b} = ${result}`);
    return result;
}

// 导出常量
export const PI = 3.14159;
export const E = 2.71828;

console.log(`数学常量已定义:PI = ${PI}, E = ${E}`);
// "数学常量已定义:PI = 3.14159, E = 2.71828"

// 默认导出(每个模块仅限一个)
export default class Circle {
    constructor(public radius: number) {
        console.log(`创建圆形,半径:${radius}`);
    }
    
    /**
     * 计算圆的面积
     * @returns 圆的面积
     */
    area(): number {
        const result = PI * this.radius ** 2;
        console.log(`圆面积计算:π × ${this.radius}² = ${result.toFixed(2)}`);
        return result;
    }
    
    /**
     * 计算圆的周长
     * @returns 圆的周长
     */
    circumference(): number {
        const result = 2 * PI * this.radius;
        console.log(`圆周长计算:2π × ${this.radius} = ${result.toFixed(2)}`);
        return result;
    }
}

// 📁 app.ts - 应用主文件
import Circle, { add, subtract, PI, E } from './math';

console.log('=== 模块导入演示 ===');
// "=== 模块导入演示 ==="

// 使用导入的函数
const sum = add(10, 5);
// "计算:10 + 5 = 15"
console.log(`加法结果:${sum}`); // "加法结果:15"

const difference = subtract(10, 3);
// "计算:10 - 3 = 7"
console.log(`减法结果:${difference}`); // "减法结果:7"

// 使用导入的常量
console.log(`圆周率:${PI}`); // "圆周率:3.14159"
console.log(`自然常数:${E}`); // "自然常数:2.71828"

// 使用默认导出的类
const circle = new Circle(5);
// "创建圆形,半径:5"

const area = circle.area();
// "圆面积计算:π × 5² = 78.54"
console.log(`圆面积:${area.toFixed(2)}`); // "圆面积:78.54"

const circumference = circle.circumference();
// "圆周长计算:2π × 5 = 31.42"
console.log(`圆周长:${circumference.toFixed(2)}`); // "圆周长:31.42"

🎯 高级导入技巧:灵活的"交通路线"

// 📁 utils.ts - 工具函数模块
export const formatDate = (date: Date): string => {
    const formatted = date.toISOString().split('T')[0];
    console.log(`格式化日期:${date} -> ${formatted}`);
    return formatted;
};

export const formatCurrency = (amount: number): string => {
    const formatted = `$${amount.toFixed(2)}`;
    console.log(`格式化货币:${amount} -> ${formatted}`);
    return formatted;
};

export const generateId = (): string => {
    const id = Math.random().toString(36).substr(2, 9);
    console.log(`生成ID:${id}`);
    return id;
};

// 📁 advanced-import.ts - 高级导入示例

// 1. 别名导入 - 避免命名冲突
import { PI as MathPI } from './math';
import { formatDate as dateFormatter } from './utils';

console.log('=== 别名导入演示 ===');
// "=== 别名导入演示 ==="

console.log(`数学常量π:${MathPI}`); // "数学常量π:3.14159"

const today = new Date();
const formattedToday = dateFormatter(today);
// "格式化日期:Mon Jan 01 2024 12:00:00 GMT+0800 (CST) -> 2024-01-01"
console.log(`今天的日期:${formattedToday}`); // "今天的日期:2024-01-01"

// 2. 整体导入 - 命名空间式访问
import * as MathUtils from './math';
import * as Utils from './utils';

console.log('=== 整体导入演示 ===');
// "=== 整体导入演示 ==="

const result = MathUtils.add(20, 30);
// "计算:20 + 30 = 50"
console.log(`使用命名空间调用:${result}`); // "使用命名空间调用:50"

const newCircle = new MathUtils.default(10);
// "创建圆形,半径:10"

const price = 99.99;
const formattedPrice = Utils.formatCurrency(price);
// "格式化货币:99.99 -> $99.99"
console.log(`格式化价格:${formattedPrice}`); // "格式化价格:$99.99"

const uniqueId = Utils.generateId();
// "生成ID:abc123def"
console.log(`生成的ID:${uniqueId}`); // "生成的ID:abc123def"

// 3. 动态导入 - 按需加载
async function loadMathModule() {
    console.log('开始动态加载数学模块...');
    // "开始动态加载数学模块..."
    
    try {
        const mathModule = await import('./math');
        console.log('数学模块加载成功');
        // "数学模块加载成功"
        
        const dynamicResult = mathModule.add(100, 200);
        // "计算:100 + 200 = 300"
        console.log(`动态导入计算结果:${dynamicResult}`); // "动态导入计算结果:300"
        
        return mathModule;
    } catch (error) {
        console.error('模块加载失败:', error);
        return null;
    }
}

// 使用动态导入
loadMathModule().then(module => {
    if (module) {
        console.log('动态导入演示完成');
        // "动态导入演示完成"
    }
});

🌟 模块的核心优势

优势特性说明实际效果
明确依赖import/export明确声明依赖关系便于代码分析和优化
静态分析编译时确定模块结构支持Tree Shaking等优化
作用域隔离每个模块有独立作用域避免全局变量污染
浏览器支持原生支持<script type="module">无需额外转换工具
按需加载支持动态import()提升应用性能

8.2 命名空间——TypeScript的"老城区规划" 🏛️

命名空间(Namespaces)是TypeScript早期的代码组织方式,就像城市中的传统街区一样,虽然不如现代模块系统先进,但在特定场景下仍有其价值。

🏗️ 基础命名空间:传统的"街区规划"

// 📁 shapes.ts - 图形命名空间
namespace Shapes {
    // 导出接口
    export interface Point {
        x: number;
        y: number;
    }
    
    export interface Circle {
        center: Point;
        radius: number;
    }
    
    // 导出类
    export class Rectangle {
        constructor(
            public width: number, 
            public height: number,
            public position: Point = { x: 0, y: 0 }
        ) {
            console.log(`创建矩形:宽${width} × 高${height},位置(${position.x}, ${position.y})`);
        }
        
        /**
         * 计算矩形面积
         * @returns 矩形面积
         */
        area(): number {
            const result = this.width * this.height;
            console.log(`矩形面积:${this.width} × ${this.height} = ${result}`);
            return result;
        }    
        
        /**
         * 移动矩形位置
         * @param newPosition 新位置
         */
        moveTo(newPosition: Point): void {
            console.log(`移动矩形:从(${this.position.x}, ${this.position.y})到(${newPosition.x}, ${newPosition.y})`);
            this.position = newPosition;
        }
    }
    
    // 导出函数
    export function calculateDistance(p1: Point, p2: Point): number {
        const distance = Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
        console.log(`计算距离:(${p1.x}, ${p1.y})到(${p2.x}, ${p2.y}) = ${distance.toFixed(2)}`);
        return distance;
    }
    
    // 内部函数(不导出)
    function validatePoint(point: Point): boolean {
        const isValid = typeof point.x === 'number' && typeof point.y === 'number';
        console.log(`验证点坐标:(${point.x}, ${point.y}) - ${isValid ? '有效' : '无效'}`);
        return isValid;
    }
    
    export function createValidPoint(x: number, y: number): Point | null {
        const point = { x, y };
        return validatePoint(point) ? point : null;
    }
}

// 📁 app.ts - 使用命名空间
/// <reference path="shapes.ts" />

console.log('=== 命名空间演示 ===');
// "=== 命名空间演示 ==="

// 创建点对象
const point1: Shapes.Point = { x: 10, y: 20 };
const point2: Shapes.Point = { x: 30, y: 40 };

console.log(`点1坐标:(${point1.x}, ${point1.y})`); // "点1坐标:(10, 20)"
console.log(`点2坐标:(${point2.x}, ${point2.y})`); // "点2坐标:(30, 40)"

// 计算两点距离
const distance = Shapes.calculateDistance(point1, point2);
// "计算距离:(10, 20)到(30, 40) = 28.28"
console.log(`两点距离:${distance.toFixed(2)}`); // "两点距离:28.28"

// 创建矩形
const rect = new Shapes.Rectangle(100, 50, point1);
// "创建矩形:宽100 × 高50,位置(10, 20)"

const rectArea = rect.area();
// "矩形面积:100 × 50 = 5000"
console.log(`矩形面积:${rectArea}`); // "矩形面积:5000"

// 移动矩形
rect.moveTo(point2);
// "移动矩形:从(10, 20)到(30, 40)"

// 创建圆形对象
const circle: Shapes.Circle = {
    center: { x: 0, y: 0 },
    radius: 25
};

console.log(`圆心:(${circle.center.x}, ${circle.center.y}),半径:${circle.radius}`); 
// "圆心:(0, 0),半径:25"

// 验证点坐标
const validPoint = Shapes.createValidPoint(15, 25);
if (validPoint) {
    console.log(`创建有效点:(${validPoint.x}, ${validPoint.y})`);
    // "验证点坐标:(15, 25) - 有效"
    // "创建有效点:(15, 25)"
}

🏢 嵌套命名空间:多层级的"城区规划"

// 📁 app-system.ts - 应用系统命名空间
namespace App {
    // 用户管理子命名空间
    export namespace User {
        export interface UserInfo {
            id: string;
            name: string;
            email: string;
            role: 'admin' | 'user' | 'guest';
        }
        
        export class UserManager {
            private users: UserInfo[] = [];
            
            /**
             * 添加用户
             * @param user 用户信息
             */
            addUser(user: UserInfo): void {
                this.users.push(user);
                console.log(`添加用户:${user.name} (${user.role})`);
                console.log(`当前用户总数:${this.users.length}`);
            }
            
            /**
             * 查找用户
             * @param id 用户ID
             * @returns 用户信息或undefined
             */
            findUser(id: string): UserInfo | undefined {
                const user = this.users.find(u => u.id === id);
                console.log(`查找用户 ${id}${user ? '找到' : '未找到'}`);
                return user;
            }
            
            /**
             * 获取所有用户
             * @returns 用户列表
             */
            getAllUsers(): UserInfo[] {
                console.log(`获取所有用户,共${this.users.length}个`);
                return [...this.users];
            }
        }
    }
    
    // 工具函数子命名空间
    export namespace Utils {
        /**
         * 记录日志
         * @param level 日志级别
         * @param message 日志消息
         */
        export function log(level: 'info' | 'warn' | 'error', message: string): void {
            const timestamp = new Date().toISOString();
            const logMessage = `[${timestamp}] ${level.toUpperCase()}: ${message}`;
            console.log(logMessage);
        }
        
        /**
         * 生成唯一ID
         * @param prefix 前缀
         * @returns 唯一ID
         */
        export function generateId(prefix: string = 'id'): string {
            const id = `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
            console.log(`生成ID:${id}`);
            return id;
        }
        
        /**
         * 延迟执行
         * @param ms 延迟毫秒数
         * @returns Promise
         */
        export function delay(ms: number): Promise<void> {
            console.log(`开始延迟 ${ms}ms`);
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log(`延迟 ${ms}ms 完成`);
                    resolve();
                }, ms);
            });
        }
    }
    
    // 配置子命名空间
    export namespace Config {
        export const APP_NAME = 'TypeScript Demo App';
        export const VERSION = '1.0.0';
        export const DEBUG = true;
        
        export interface DatabaseConfig {
            host: string;
            port: number;
            database: string;
        }
        
        export const database: DatabaseConfig = {
            host: 'localhost',
            port: 5432,
            database: 'demo_db'
        };
        
        /**
         * 获取应用信息
         * @returns 应用信息字符串
         */
        export function getAppInfo(): string {
            const info = `${APP_NAME} v${VERSION} (Debug: ${DEBUG})`;
            console.log(`应用信息:${info}`);
            return info;
        }
    }
}

// 使用嵌套命名空间
console.log('=== 嵌套命名空间演示 ===');
// "=== 嵌套命名空间演示 ==="

// 获取应用信息
const appInfo = App.Config.getAppInfo();
// "应用信息:TypeScript Demo App v1.0.0 (Debug: true)"
console.log(appInfo); // "TypeScript Demo App v1.0.0 (Debug: true)"

// 创建用户管理器
const userManager = new App.User.UserManager();

// 生成用户ID
const userId1 = App.Utils.generateId('user');
// "生成ID:user_1704067200000_abc12"
const userId2 = App.Utils.generateId('user');
// "生成ID:user_1704067200001_def34"

// 添加用户
const user1: App.User.UserInfo = {
    id: userId1,
    name: '张三',
    email: 'zhangsan@example.com',
    role: 'admin'
};

const user2: App.User.UserInfo = {
    id: userId2,
    name: '李四',
    email: 'lisi@example.com',
    role: 'user'
};

userManager.addUser(user1);
// "添加用户:张三 (admin)"
// "当前用户总数:1"

userManager.addUser(user2);
// "添加用户:李四 (user)"
// "当前用户总数:2"

// 查找用户
const foundUser = userManager.findUser(userId1);
// "查找用户 user_1704067200000_abc12:找到"
if (foundUser) {
    console.log(`找到用户:${foundUser.name}`);
    // "找到用户:张三"
}

// 记录日志
App.Utils.log('info', '用户管理系统初始化完成');
// "[2024-01-01T12:00:00.000Z] INFO: 用户管理系统初始化完成"

App.Utils.log('warn', '这是一个警告消息');
// "[2024-01-01T12:00:00.001Z] WARN: 这是一个警告消息"

// 异步延迟示例
App.Utils.delay(1000).then(() => {
    App.Utils.log('info', '延迟操作完成');
    // "开始延迟 1000ms"
    // (1秒后)
    // "延迟 1000ms 完成"
    // "[2024-01-01T12:00:01.000Z] INFO: 延迟操作完成"
});

⚠️ 命名空间的适用场景

使用场景推荐度原因
新项目❌ 不推荐ES模块更现代、标准
旧项目迁移✅ 推荐兼容现有代码结构
全局脚本环境✅ 推荐避免全局污染
类型声明文件✅ 推荐组织复杂类型定义
浏览器直接使用⚡ 可选无需构建工具

8.3 模块解析策略——寻找模块的"导航规则" 🗺️

模块解析(Module Resolution)是TypeScript编译器定位导入模块的过程,就像城市的GPS导航系统一样,决定了如何找到目标"地址"。

🧭 解析策略对比:两种"导航模式"

策略类型说明适用场景配置方式
classicTypeScript传统方式已弃用,仅兼容"moduleResolution": "classic"
node模拟Node.js的require()现代项目推荐"moduleResolution": "node"
bundler现代打包工具优化Webpack/Vite项目"moduleResolution": "bundler"

🔍 Node策略解析过程:详细的"寻址流程"

// 📁 项目结构示例
/*
project/
├── src/
│   ├── app.ts
│   ├── services/
│   │   ├── user.ts
│   │   ├── user.d.ts
│   │   └── api/
│   │       ├── index.ts
│   │       └── client.ts
│   └── utils/
│       ├── helpers.ts
│       └── index.ts
├── node_modules/
│   └── lodash/
│       ├── package.json
│       └── index.js
└── tsconfig.json
*/

// 📁 src/app.ts - 演示模块解析
console.log('=== 模块解析演示 ===');
// "=== 模块解析演示 ==="

// 1. 相对路径导入 - 解析过程演示
import { getUserInfo } from './services/user';
/*
解析顺序:
1. 检查 ./services/user.ts ✓
2. 检查 ./services/user.tsx
3. 检查 ./services/user.d.ts
4. 检查 ./services/user/package.json
5. 检查 ./services/user/index.ts
*/

const user = getUserInfo('123');
console.log('用户信息获取完成');
// "用户信息获取完成"

// 2. 目录导入 - 自动查找index文件
import { formatDate, formatCurrency } from './utils';
/*
解析顺序:
1. 检查 ./utils.ts
2. 检查 ./utils.tsx
3. 检查 ./utils.d.ts
4. 检查 ./utils/package.json (查找"types"字段)
5. 检查 ./utils/index.ts ✓
*/

const today = new Date();
const formattedDate = formatDate(today);
console.log(`格式化日期:${formattedDate}`);
// "格式化日期:2024-01-01"

const price = 99.99;
const formattedPrice = formatCurrency(price);
console.log(`格式化价格:${formattedPrice}`);
// "格式化价格:$99.99"

// 3. 非相对路径导入 - 查找node_modules
import _ from 'lodash';
/*
解析顺序:
1. 检查 node_modules/lodash.ts
2. 检查 node_modules/lodash.tsx
3. 检查 node_modules/lodash.d.ts
4. 检查 node_modules/lodash/package.json (查找"types"或"typings"字段) ✓
5. 检查 node_modules/lodash/index.ts
6. 向上级目录查找 ../node_modules/lodash/...
*/

const numbers = [1, 2, 3, 4, 5];
const doubled = _.map(numbers, n => n * 2);
console.log(`数组映射结果:${doubled}`);
// "数组映射结果:2,4,6,8,10"

// 📁 src/services/user.ts - 用户服务模块
export interface User {
    id: string;
    name: string;
    email: string;
    createdAt: Date;
}

/**
 * 获取用户信息
 * @param userId 用户ID
 * @returns 用户信息
 */
export function getUserInfo(userId: string): User {
    console.log(`获取用户信息:${userId}`);
    
    // 模拟数据库查询
    const user: User = {
        id: userId,
        name: `用户${userId}`,
        email: `user${userId}@example.com`,
        createdAt: new Date()
    };
    
    console.log(`用户信息:${JSON.stringify(user, null, 2)}`);
    return user;
}

/**
 * 更新用户信息
 * @param userId 用户ID
 * @param updates 更新数据
 * @returns 更新后的用户信息
 */
export function updateUser(userId: string, updates: Partial<User>): User {
    console.log(`更新用户 ${userId}:`, updates);
    
    const currentUser = getUserInfo(userId);
    const updatedUser = { ...currentUser, ...updates };
    
    console.log(`用户更新完成:${updatedUser.name}`);
    return updatedUser;
}

// 📁 src/utils/index.ts - 工具函数入口
/**
 * 格式化日期
 * @param date 日期对象
 * @returns 格式化的日期字符串
 */
export function formatDate(date: Date): string {
    const formatted = date.toISOString().split('T')[0];
    console.log(`日期格式化:${date.toDateString()} -> ${formatted}`);
    return formatted;
}

/**
 * 格式化货币
 * @param amount 金额
 * @param currency 货币符号
 * @returns 格式化的货币字符串
 */
export function formatCurrency(amount: number, currency: string = '$'): string {
    const formatted = `${currency}${amount.toFixed(2)}`;
    console.log(`货币格式化:${amount} -> ${formatted}`);
    return formatted;
}

/**
 * 生成随机字符串
 * @param length 字符串长度
 * @returns 随机字符串
 */
export function randomString(length: number = 8): string {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    
    for (let i = 0; i < length; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    
    console.log(`生成随机字符串:${result}`);
    return result;
}

// 重新导出其他工具
export * from './helpers';

// 📁 src/utils/helpers.ts - 辅助工具函数
/**
 * 防抖函数
 * @param func 要防抖的函数
 * @param delay 延迟时间
 * @returns 防抖后的函数
 */
export function debounce<T extends (...args: any[]) => any>(
    func: T, 
    delay: number
): (...args: Parameters<T>) => void {
    let timeoutId: NodeJS.Timeout;
    
    return (...args: Parameters<T>) => {
        console.log(`防抖函数调用,延迟${delay}ms`);
        
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            console.log('防抖函数执行');
            func.apply(null, args);
        }, delay);
    };
}

/**
 * 节流函数
 * @param func 要节流的函数
 * @param delay 节流间隔
 * @returns 节流后的函数
 */
export function throttle<T extends (...args: any[]) => any>(
    func: T, 
    delay: number
): (...args: Parameters<T>) => void {
    let lastCall = 0;
    
    return (...args: Parameters<T>) => {
        const now = Date.now();
        
        if (now - lastCall >= delay) {
            console.log('节流函数执行');
            lastCall = now;
            func.apply(null, args);
        } else {
            console.log(`节流函数跳过,距离上次调用${now - lastCall}ms`);
        }
    };
}

🛠️ 路径别名配置:自定义"快捷路径"

// 📁 tsconfig.json - TypeScript配置文件
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"],
      "@services/*": ["services/*"],
      "@utils/*": ["utils/*"],
      "@components/*": ["components/*"],
      "@types/*": ["types/*"]
    },
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
// 📁 src/app-with-aliases.ts - 使用路径别名
console.log('=== 路径别名演示 ===');
// "=== 路径别名演示 ==="

// 使用别名导入 - 简洁清晰
import { getUserInfo, updateUser } from '@services/user';
import { formatDate, formatCurrency, debounce } from '@utils';
import type { User } from '@services/user';

// 创建防抖函数
const debouncedLog = debounce((message: string) => {
    console.log(`防抖日志:${message}`);
}, 500);

// 模拟用户操作
const userId = 'user_001';
const user = getUserInfo(userId);
// "获取用户信息:user_001"
// "用户信息:{...}"

// 更新用户信息
const updatedUser = updateUser(userId, {
    name: '张三',
    email: 'zhangsan@example.com'
});
// "更新用户 user_001:" { name: '张三', email: 'zhangsan@example.com' }
// "获取用户信息:user_001"
// "用户信息:{...}"
// "用户更新完成:张三"

// 格式化显示
const displayDate = formatDate(updatedUser.createdAt);
const displayPrice = formatCurrency(199.99);

console.log(`用户创建日期:${displayDate}`);
// "日期格式化:Mon Jan 01 2024 -> 2024-01-01"
// "用户创建日期:2024-01-01"

console.log(`商品价格:${displayPrice}`);
// "货币格式化:199.99 -> $199.99"
// "商品价格:$199.99"

// 测试防抖函数
debouncedLog('第一次调用');
// "防抖函数调用,延迟500ms"
debouncedLog('第二次调用');
// "防抖函数调用,延迟500ms"
debouncedLog('第三次调用');
// "防抖函数调用,延迟500ms"
// (500ms后)
// "防抖函数执行"
// "防抖日志:第三次调用"

🎯 模块解析最佳实践

  1. 优先使用相对路径:明确的依赖关系
  2. 配置路径别名:简化长路径导入
  3. 统一导入风格:保持代码一致性
  4. 合理组织目录:便于模块查找
  5. 使用index文件:简化目录导入

8.4 声明合并——TypeScript的"和平统一" 🤝

声明合并(Declaration Merging)是TypeScript的独特功能,允许将多个同名声明合并为单个定义,就像城市规划中的"区域整合"一样。

🔗 接口合并:扩展现有定义

// 📁 user-base.ts - 基础用户接口
interface User {
    id: string;
    name: string;
}

console.log('=== 接口合并演示 ===');
// "=== 接口合并演示 ==="

// 第一次扩展 - 添加联系信息
interface User {
    email: string;
    phone?: string;
}

// 第二次扩展 - 添加权限信息
interface User {
    role: 'admin' | 'user' | 'guest';
    permissions: string[];
    lastLogin?: Date;
}

// 合并结果:
// interface User {
//     id: string;
//     name: string;
//     email: string;
//     phone?: string;
//     role: 'admin' | 'user' | 'guest';
//     permissions: string[];
//     lastLogin?: Date;
// }

/**
 * 创建用户对象
 * @param userData 用户数据
 * @returns 完整的用户对象
 */
function createUser(userData: Partial<User> & Pick<User, 'id' | 'name' | 'email' | 'role'>): User {
    const user: User = {
        id: userData.id,
        name: userData.name,
        email: userData.email,
        role: userData.role,
        permissions: userData.permissions || [],
        phone: userData.phone,
        lastLogin: userData.lastLogin
    };
    
    console.log(`创建用户:${user.name} (${user.role})`);
    console.log(`权限列表:${user.permissions.join(', ') || '无'}`);
    
    return user;
}

// 使用合并后的接口
const adminUser = createUser({
    id: 'admin_001',
    name: '管理员',
    email: 'admin@example.com',
    role: 'admin',
    permissions: ['read', 'write', 'delete'],
    phone: '13800138000',
    lastLogin: new Date()
});
// "创建用户:管理员 (admin)"
// "权限列表:read, write, delete"

const regularUser = createUser({
    id: 'user_001',
    name: '普通用户',
    email: 'user@example.com',
    role: 'user',
    permissions: ['read']
});
// "创建用户:普通用户 (user)"
// "权限列表:read"

console.log(`管理员邮箱:${adminUser.email}`); // "管理员邮箱:admin@example.com"
console.log(`普通用户权限:${regularUser.permissions.length}个`); // "普通用户权限:1个"

🏢 命名空间合并:功能模块整合

// 📁 api-core.ts - API核心功能
namespace API {
    export const BASE_URL = 'https://api.example.com';
    export const VERSION = 'v1';
    
    /**
     * 构建完整的API URL
     * @param endpoint 端点路径
     * @returns 完整URL
     */
    export function buildUrl(endpoint: string): string {
        const url = `${BASE_URL}/${VERSION}${endpoint}`;
        console.log(`构建API URL:${url}`);
        return url;
    }
}

// 📁 api-auth.ts - API认证功能
namespace API {
    export interface AuthToken {
        access_token: string;
        refresh_token: string;
        expires_in: number;
    }
    
    let currentToken: AuthToken | null = null;
    
    /**
     * 设置认证令牌
     * @param token 认证令牌
     */
    export function setAuthToken(token: AuthToken): void {
        currentToken = token;
        console.log(`设置认证令牌,过期时间:${token.expires_in}秒`);
    }
    
    /**
     * 获取认证头部
     * @returns 认证头部对象
     */
    export function getAuthHeaders(): Record<string, string> {
        if (!currentToken) {
            console.log('警告:未设置认证令牌');
            return {};
        }
        
        const headers = {
            'Authorization': `Bearer ${currentToken.access_token}`,
            'Content-Type': 'application/json'
        };
        
        console.log('获取认证头部');
        return headers;
    }
    
    /**
     * 检查令牌是否有效
     * @returns 是否有效
     */
    export function isTokenValid(): boolean {
        if (!currentToken) {
            console.log('令牌检查:未设置令牌');
            return false;
        }
        
        // 简化的过期检查
        const isValid = currentToken.expires_in > 0;
        console.log(`令牌检查:${isValid ? '有效' : '已过期'}`);
        return isValid;
    }
}

// 📁 api-requests.ts - API请求功能
namespace API {
    export interface RequestOptions {
        method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
        body?: any;
        headers?: Record<string, string>;
    }
    
    /**
     * 发送API请求
     * @param endpoint 端点路径
     * @param options 请求选项
     * @returns Promise响应
     */
    export async function request<T = any>(
        endpoint: string, 
        options: RequestOptions = {}
    ): Promise<T> {
        const url = buildUrl(endpoint); // 使用合并的函数
        const authHeaders = getAuthHeaders(); // 使用合并的函数
        
        const requestOptions = {
            method: options.method || 'GET',
            headers: {
                ...authHeaders,
                ...options.headers
            },
            body: options.body ? JSON.stringify(options.body) : undefined
        };
        
        console.log(`发送${requestOptions.method}请求到:${url}`);
        console.log(`请求头:`, requestOptions.headers);
        
        // 模拟网络请求
        return new Promise((resolve) => {
            setTimeout(() => {
                const mockResponse = {
                    success: true,
                    data: { message: '请求成功', endpoint },
                    timestamp: new Date().toISOString()
                } as T;
                
                console.log(`请求响应:`, mockResponse);
                resolve(mockResponse);
            }, 1000);
        });
    }
    
    /**
     * GET请求快捷方法
     * @param endpoint 端点路径
     * @returns Promise响应
     */
    export function get<T = any>(endpoint: string): Promise<T> {
        return request<T>(endpoint, { method: 'GET' });
    }
    
    /**
     * POST请求快捷方法
     * @param endpoint 端点路径
     * @param data 请求数据
     * @returns Promise响应
     */
    export function post<T = any>(endpoint: string, data: any): Promise<T> {
        return request<T>(endpoint, { method: 'POST', body: data });
    }
}

// 使用合并后的命名空间
console.log('=== 命名空间合并演示 ===');
// "=== 命名空间合并演示 ==="

// 设置认证令牌
const token: API.AuthToken = {
    access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    refresh_token: 'refresh_token_here',
    expires_in: 3600
};

API.setAuthToken(token);
// "设置认证令牌,过期时间:3600秒"

// 检查令牌状态
const isValid = API.isTokenValid();
// "令牌检查:有效"
console.log(`令牌状态:${isValid ? '有效' : '无效'}`); // "令牌状态:有效"

// 发送GET请求
API.get('/users').then(response => {
    console.log('GET请求完成');
    // "构建API URL:https://api.example.com/v1/users"
    // "获取认证头部"
    // "发送GET请求到:https://api.example.com/v1/users"
    // "请求头:" { Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', Content-Type: 'application/json' }
    // (1秒后)
    // "请求响应:" { success: true, data: { message: '请求成功', endpoint: '/users' }, timestamp: '2024-01-01T12:00:00.000Z' }
    // "GET请求完成"
});

// 发送POST请求
const userData = {
    name: '新用户',
    email: 'newuser@example.com'
};

API.post('/users', userData).then(response => {
    console.log('POST请求完成');
    // "构建API URL:https://api.example.com/v1/users"
    // "获取认证头部"
    // "发送POST请求到:https://api.example.com/v1/users"
    // "请求头:" { Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', Content-Type: 'application/json' }
    // (1秒后)
    // "请求响应:" { success: true, data: { message: '请求成功', endpoint: '/users' }, timestamp: '2024-01-01T12:00:01.000Z' }
    // "POST请求完成"
});

🎭 类与命名空间合并:功能增强

// 📁 form-validator.ts - 表单验证器
class FormValidator {
    private errors: string[] = [];
    
    constructor(private formData: Record<string, any>) {
        console.log('创建表单验证器');
        console.log('表单数据:', formData);
    }
    
    /**
     * 验证表单
     * @returns 验证是否通过
     */
    validate(): boolean {
        this.errors = [];
        console.log('开始表单验证...');
        
        // 基础验证逻辑
        for (const [key, value] of Object.entries(this.formData)) {
            if (value === undefined || value === null || value === '') {
                this.errors.push(`${key}不能为空`);
            }
        }
        
        const isValid = this.errors.length === 0;
        console.log(`验证结果:${isValid ? '通过' : '失败'}`);
        
        if (!isValid) {
            console.log('验证错误:', this.errors);
        }
        
        return isValid;
    }
    
    /**
     * 获取验证错误
     * @returns 错误列表
     */
    getErrors(): string[] {
        return [...this.errors];
    }
}

// 通过命名空间为类添加静态功能
namespace FormValidator {
    export const VERSION = '1.0.0';
    export const SUPPORTED_TYPES = ['text', 'email', 'number', 'date'];
    
    /**
     * 验证邮箱格式
     * @param email 邮箱地址
     * @returns 是否有效
     */
    export function validateEmail(email: string): boolean {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        const isValid = emailRegex.test(email);
        console.log(`邮箱验证:${email} - ${isValid ? '有效' : '无效'}`);
        return isValid;
    }
    
    /**
     * 验证手机号格式
     * @param phone 手机号
     * @returns 是否有效
     */
    export function validatePhone(phone: string): boolean {
        const phoneRegex = /^1[3-9]\d{9}$/;
        const isValid = phoneRegex.test(phone);
        console.log(`手机号验证:${phone} - ${isValid ? '有效' : '无效'}`);
        return isValid;
    }
    
    /**
     * 创建预配置的验证器
     * @param type 验证器类型
     * @returns 验证器实例
     */
    export function createValidator(type: 'user' | 'product' | 'order'): FormValidator {
        console.log(`创建${type}验证器`);
        
        const defaultData = {
            user: { name: '', email: '', phone: '' },
            product: { name: '', price: 0, category: '' },
            order: { userId: '', productId: '', quantity: 1 }
        };
        
        return new FormValidator(defaultData[type]);
    }
}

// 使用合并后的类和命名空间
console.log('=== 类与命名空间合并演示 ===');
// "=== 类与命名空间合并演示 ==="

// 访问命名空间的静态属性
console.log(`验证器版本:${FormValidator.VERSION}`); // "验证器版本:1.0.0"
console.log(`支持的类型:${FormValidator.SUPPORTED_TYPES.join(', ')}`);
// "支持的类型:text, email, number, date"

// 使用命名空间的静态方法
const email = 'user@example.com';
const phone = '13800138000';

const emailValid = FormValidator.validateEmail(email);
// "邮箱验证:user@example.com - 有效"
const phoneValid = FormValidator.validatePhone(phone);
// "手机号验证:13800138000 - 有效"

console.log(`邮箱${emailValid ? '有效' : '无效'},手机号${phoneValid ? '有效' : '无效'}`);
// "邮箱有效,手机号有效"

// 创建验证器实例
const userValidator = FormValidator.createValidator('user');
// "创建user验证器"
// "创建表单验证器"
// "表单数据:" { name: '', email: '', phone: '' }

// 验证空表单
const isValidEmpty = userValidator.validate();
// "开始表单验证..."
// "验证结果:失败"
// "验证错误:" ['name不能为空', 'email不能为空', 'phone不能为空']

console.log(`空表单验证:${isValidEmpty ? '通过' : '失败'}`); // "空表单验证:失败"

if (!isValidEmpty) {
    const errors = userValidator.getErrors();
    console.log(`错误数量:${errors.length}`);
    // "错误数量:3"
}

// 创建有效的用户验证器
const validUserData = {
    name: '张三',
    email: 'zhangsan@example.com',
    phone: '13800138000'
};

const validUserValidator = new FormValidator(validUserData);
// "创建表单验证器"
// "表单数据:" { name: '张三', email: 'zhangsan@example.com', phone: '13800138000' }

const isValidUser = validUserValidator.validate();
// "开始表单验证..."
// "验证结果:通过"

console.log(`有效表单验证:${isValidUser ? '通过' : '失败'}`); // "有效表单验证:通过"

🎯 声明合并的应用场景

合并类型使用场景优势注意事项
接口合并扩展第三方库类型类型安全的扩展属性类型必须兼容
命名空间合并模块化功能组织逐步构建复杂功能避免循环依赖
类与命名空间合并为类添加静态功能功能集中管理保持职责清晰

8.5 三斜线指令——TypeScript的"老式电报" 📡

三斜线指令(Triple-Slash Directives)是TypeScript早期的模块导入语法,就像城市中的老式电报系统一样,虽然已被现代通信取代,但在特定场景下仍有其价值。

📜 基础三斜线指令:传统的"依赖声明"

// 📁 legacy-types.d.ts - 传统类型声明文件
/// <reference path="./user-types.d.ts" />
/// <reference path="./api-types.d.ts" />
/// <reference types="node" />

console.log('=== 三斜线指令演示 ===');
// "=== 三斜线指令演示 ==="

// 📁 user-types.d.ts - 用户类型声明
declare namespace UserTypes {
    interface BasicUser {
        id: string;
        name: string;
        email: string;
    }
    
    interface AdminUser extends BasicUser {
        permissions: string[];
        lastLogin: Date;
    }
    
    type UserRole = 'admin' | 'user' | 'guest';
}

// 📁 api-types.d.ts - API类型声明
declare namespace APITypes {
    interface Response<T = any> {
        success: boolean;
        data: T;
        message: string;
        timestamp: string;
    }
    
    interface ErrorResponse {
        success: false;
        error: {
            code: number;
            message: string;
            details?: any;
        };
        timestamp: string;
    }
    
    type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
}

// 📁 legacy-app.ts - 使用三斜线指令的应用
/// <reference path="./legacy-types.d.ts" />

/**
 * 创建API响应
 * @param data 响应数据
 * @param message 响应消息
 * @returns API响应对象
 */
function createApiResponse<T>(
    data: T, 
    message: string = '操作成功'
): APITypes.Response<T> {
    const response: APITypes.Response<T> = {
        success: true,
        data,
        message,
        timestamp: new Date().toISOString()
    };
    
    console.log(`创建API响应:${message}`);
    console.log('响应数据:', response);
    
    return response;
}

/**
 * 创建错误响应
 * @param code 错误代码
 * @param message 错误消息
 * @param details 错误详情
 * @returns 错误响应对象
 */
function createErrorResponse(
    code: number, 
    message: string, 
    details?: any
): APITypes.ErrorResponse {
    const errorResponse: APITypes.ErrorResponse = {
        success: false,
        error: {
            code,
            message,
            details
        },
        timestamp: new Date().toISOString()
    };
    
    console.log(`创建错误响应:${code} - ${message}`);
     console.log('错误详情:', errorResponse.error);
     
     return errorResponse;
}

/**
 * 处理用户请求
 * @param userData 用户数据
 * @returns API响应
 */
function handleUserRequest(userData: UserTypes.BasicUser): APITypes.Response<UserTypes.BasicUser> {
    console.log('处理用户请求');
    
    try {
        // 验证用户数据
        if (!userData.id || !userData.name || !userData.email) {
            throw new Error('用户数据不完整');
        }
        
        console.log(`处理用户:${userData.name}`);
        
        return createApiResponse(userData, '用户处理成功');
        // "创建API响应:用户处理成功"
        // "响应数据:" { success: true, data: {...}, message: '用户处理成功', timestamp: '...' }
    } catch (error) {
        console.error('用户处理失败:', error);
        return createErrorResponse(400, '用户数据无效', error) as any;
        // "创建错误响应:400 - 用户数据无效"
        // "错误详情:" { code: 400, message: '用户数据无效', details: Error }
    }
}

// 使用三斜线指令的类型
const testUser: UserTypes.BasicUser = {
    id: 'user_001',
    name: '测试用户',
    email: 'test@example.com'
};

const response = handleUserRequest(testUser);
// "处理用户请求"
// "处理用户:测试用户"
// "创建API响应:用户处理成功"
// "响应数据:" {...}

console.log(`请求处理结果:${response.success ? '成功' : '失败'}`);
// "请求处理结果:成功"

// 测试错误情况
const invalidUser = { id: '', name: '', email: '' } as UserTypes.BasicUser;
const errorResponse = handleUserRequest(invalidUser);
// "处理用户请求"
// "用户处理失败:" Error: 用户数据不完整
// "创建错误响应:400 - 用户数据无效"
// "错误详情:" {...}

console.log(`错误处理结果:${errorResponse.success ? '成功' : '失败'}`);
// "错误处理结果:失败"

🎯 三斜线指令的现代替代方案

// 📁 tsconfig.json - 现代配置方式
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "types": ["node", "@types/lodash"],
    "typeRoots": ["./node_modules/@types", "./src/types"],
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
// 📁 modern-approach.ts - 现代模块化方式
import type { User } from './types/user';
import type { APIResponse } from './types/api';

console.log('=== 现代模块化演示 ===');
// "=== 现代模块化演示 ==="

/**
 * 现代化的用户处理函数
 * @param user 用户对象
 * @returns API响应
 */
function processUser(user: User): APIResponse<User> {
    console.log(`现代化处理用户:${user.name}`);
    
    const response: APIResponse<User> = {
        success: true,
        data: user,
        message: '现代化处理成功',
        timestamp: new Date().toISOString()
    };
    
    console.log('现代化响应:', response);
    return response;
}

// 📁 src/types/user.ts - 现代类型定义
export interface User {
    id: string;
    name: string;
    email: string;
    role?: 'admin' | 'user' | 'guest';
}

export interface AdminUser extends User {
    permissions: string[];
    lastLogin: Date;
}

export type UserRole = 'admin' | 'user' | 'guest';

// 📁 src/types/api.ts - 现代API类型
export interface APIResponse<T = any> {
    success: boolean;
    data: T;
    message: string;
    timestamp: string;
}

export interface APIError {
    code: number;
    message: string;
    details?: any;
}

export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';

⚠️ 三斜线指令的使用建议

使用场景推荐度现代替代方案
新项目❌ 不推荐ES模块 + import/export
类型声明文件⚡ 可选模块化类型定义
全局类型扩展✅ 推荐declare global + 模块
旧项目维护✅ 推荐逐步迁移到ES模块
库的类型定义⚡ 可选现代声明文件格式

🏗️ 实战案例:构建模块化的任务管理系统

让我们通过一个完整的任务管理系统来演示模块化设计的最佳实践。

📁 项目结构设计

task-manager/
├── src/
│   ├── types/           # 类型定义
│   │   ├── index.ts
│   │   ├── task.ts
│   │   └── user.ts
│   ├── services/        # 业务服务
│   │   ├── index.ts
│   │   ├── taskService.ts
│   │   └── userService.ts
│   ├── utils/           # 工具函数
│   │   ├── index.ts
│   │   ├── validation.ts
│   │   └── formatting.ts
│   ├── components/      # 组件模块
│   │   ├── index.ts
│   │   ├── TaskList.ts
│   │   └── UserProfile.ts
│   └── app.ts          # 应用入口
├── tsconfig.json
└── package.json

🎯 类型定义模块

// 📁 src/types/task.ts - 任务类型定义
export interface Task {
    id: string;
    title: string;
    description: string;
    status: TaskStatus;
    priority: TaskPriority;
    assigneeId: string;
    createdAt: Date;
    updatedAt: Date;
    dueDate?: Date;
}

export type TaskStatus = 'pending' | 'in-progress' | 'completed' | 'cancelled';
export type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';

export interface CreateTaskRequest {
    title: string;
    description: string;
    priority: TaskPriority;
    assigneeId: string;
    dueDate?: Date;
}

export interface UpdateTaskRequest {
    title?: string;
    description?: string;
    status?: TaskStatus;
    priority?: TaskPriority;
    dueDate?: Date;
}

export interface TaskFilter {
    status?: TaskStatus;
    priority?: TaskPriority;
    assigneeId?: string;
    dueBefore?: Date;
}

// 📁 src/types/user.ts - 用户类型定义
export interface User {
    id: string;
    name: string;
    email: string;
    role: UserRole;
    department: string;
    createdAt: Date;
}

export type UserRole = 'admin' | 'manager' | 'developer' | 'tester';

export interface CreateUserRequest {
    name: string;
    email: string;
    role: UserRole;
    department: string;
}

// 📁 src/types/index.ts - 类型入口文件
export * from './task';
export * from './user';

// 通用响应类型
export interface APIResponse<T = any> {
    success: boolean;
    data: T;
    message: string;
    timestamp: string;
}

export interface PaginatedResponse<T> extends APIResponse<T[]> {
    pagination: {
        page: number;
        limit: number;
        total: number;
        totalPages: number;
    };
}

🛠️ 服务层模块

// 📁 src/services/taskService.ts - 任务服务
import type { 
    Task, 
    CreateTaskRequest, 
    UpdateTaskRequest, 
    TaskFilter,
    APIResponse,
    PaginatedResponse 
} from '@types';
import { generateId, formatDate } from '@utils';
import { validateTask } from '@utils/validation';

export class TaskService {
    private tasks: Task[] = [];                      // 任务列表
    
    /**
     * 创建新任务
     * @param request 创建任务请求
     * @returns 创建的任务
     */
    async createTask(request: CreateTaskRequest): Promise<APIResponse<Task>> {
        console.log('创建新任务:', request.title);
        
        try {
            // 验证请求数据
            const validation = validateTask(request);
            if (!validation.isValid) {
                console.log('任务验证失败:', validation.errors);
                return {
                    success: false,
                    data: null as any,
                    message: `验证失败:${validation.errors.join(', ')}`,
                    timestamp: new Date().toISOString()
                };
            }
            
            const task: Task = {
                id: generateId('task'),
                title: request.title,
                description: request.description,
                status: 'pending',
                priority: request.priority,
                assigneeId: request.assigneeId,
                createdAt: new Date(),
                updatedAt: new Date(),
                dueDate: request.dueDate
            };
            
            this.tasks.push(task);
            
            console.log(`任务创建成功:${task.id}`);
            console.log(`当前任务总数:${this.tasks.length}`);
            
            return {
                success: true,
                data: task,
                message: '任务创建成功',
                timestamp: new Date().toISOString()
            };
        } catch (error) {
            console.error('创建任务失败:', error);
            return {
                success: false,
                data: null as any,
                message: '创建任务失败',
                timestamp: new Date().toISOString()
            };
        }
    }
    
    /**
     * 获取任务列表
     * @param filter 过滤条件
     * @param page 页码
     * @param limit 每页数量
     * @returns 分页任务列表
     */
    async getTasks(
        filter: TaskFilter = {}, 
        page: number = 1, 
        limit: number = 10
    ): Promise<PaginatedResponse<Task>> {
        console.log(`获取任务列表:页码${page},每页${limit}条`);
        console.log('过滤条件:', filter);
        
        let filteredTasks = this.tasks;
        
        // 应用过滤条件
        if (filter.status) {
            filteredTasks = filteredTasks.filter(task => task.status === filter.status);
            console.log(`状态过滤后:${filteredTasks.length}条`);
        }
        
        if (filter.priority) {
            filteredTasks = filteredTasks.filter(task => task.priority === filter.priority);
            console.log(`优先级过滤后:${filteredTasks.length}条`);
        }
        
        if (filter.assigneeId) {
            filteredTasks = filteredTasks.filter(task => task.assigneeId === filter.assigneeId);
            console.log(`负责人过滤后:${filteredTasks.length}条`);
        }
        
        // 分页处理
        const total = filteredTasks.length;
        const totalPages = Math.ceil(total / limit);
        const startIndex = (page - 1) * limit;
        const endIndex = startIndex + limit;
        const paginatedTasks = filteredTasks.slice(startIndex, endIndex);
        
        console.log(`分页结果:第${page}页,共${totalPages}页,当前页${paginatedTasks.length}条`);
        
        return {
            success: true,
            data: paginatedTasks,
            message: '获取任务列表成功',
            timestamp: new Date().toISOString(),
            pagination: {
                page,
                limit,
                total,
                totalPages
            }
        };
    }
    
    /**
     * 更新任务
     * @param taskId 任务ID
     * @param updates 更新数据
     * @returns 更新后的任务
     */
    async updateTask(taskId: string, updates: UpdateTaskRequest): Promise<APIResponse<Task>> {
        console.log(`更新任务:${taskId}`);
        console.log('更新内容:', updates);
        
        const taskIndex = this.tasks.findIndex(task => task.id === taskId);
        
        if (taskIndex === -1) {
            console.log(`任务不存在:${taskId}`);
            return {
                success: false,
                data: null as any,
                message: '任务不存在',
                timestamp: new Date().toISOString()
            };
        }
        
        const task = this.tasks[taskIndex];
        const updatedTask: Task = {
            ...task,
            ...updates,
            updatedAt: new Date()
        };
        
        this.tasks[taskIndex] = updatedTask;
        
        console.log(`任务更新成功:${updatedTask.title}`);
        
        return {
            success: true,
            data: updatedTask,
            message: '任务更新成功',
            timestamp: new Date().toISOString()
        };
    }
    
    /**
     * 删除任务
     * @param taskId 任务ID
     * @returns 删除结果
     */
    async deleteTask(taskId: string): Promise<APIResponse<boolean>> {
        console.log(`删除任务:${taskId}`);
        
        const taskIndex = this.tasks.findIndex(task => task.id === taskId);
        
        if (taskIndex === -1) {
            console.log(`任务不存在:${taskId}`);
            return {
                success: false,
                data: false,
                message: '任务不存在',
                timestamp: new Date().toISOString()
            };
        }
        
        const deletedTask = this.tasks.splice(taskIndex, 1)[0];
        
        console.log(`任务删除成功:${deletedTask.title}`);
        console.log(`剩余任务数:${this.tasks.length}`);
        
        return {
            success: true,
            data: true,
            message: '任务删除成功',
            timestamp: new Date().toISOString()
        };
    }
}

// 📁 src/services/userService.ts - 用户服务
import type { User, CreateUserRequest, APIResponse } from '@types';
import { generateId } from '@utils';
import { validateUser } from '@utils/validation';

export class UserService {
    private users: User[] = [];
    
    /**
     * 创建用户
     * @param request 创建用户请求
     * @returns 创建的用户
     */
    async createUser(request: CreateUserRequest): Promise<APIResponse<User>> {
        console.log('创建新用户:', request.name);
        
        try {
            const validation = validateUser(request);
            if (!validation.isValid) {
                console.log('用户验证失败:', validation.errors);
                return {
                    success: false,
                    data: null as any,
                    message: `验证失败:${validation.errors.join(', ')}`,
                    timestamp: new Date().toISOString()
                };
            }
            
            const user: User = {
                id: generateId('user'),
                name: request.name,
                email: request.email,
                role: request.role,
                department: request.department,
                createdAt: new Date()
            };
            
            this.users.push(user);
            
            console.log(`用户创建成功:${user.id}`);
            console.log(`当前用户总数:${this.users.length}`);
            
            return {
                success: true,
                data: user,
                message: '用户创建成功',
                timestamp: new Date().toISOString()
            };
        } catch (error) {
            console.error('创建用户失败:', error);
            return {
                success: false,
                data: null as any,
                message: '创建用户失败',
                timestamp: new Date().toISOString()
            };
        }
    }
    
    /**
     * 获取所有用户
     * @returns 用户列表
     */
    async getUsers(): Promise<APIResponse<User[]>> {
        console.log(`获取所有用户,共${this.users.length}个`);
        
        return {
            success: true,
            data: [...this.users],
            message: '获取用户列表成功',
            timestamp: new Date().toISOString()
        };
    }
    
    /**
     * 根据ID获取用户
     * @param userId 用户ID
     * @returns 用户信息
     */
    async getUserById(userId: string): Promise<APIResponse<User>> {
        console.log(`获取用户:${userId}`);
        
        const user = this.users.find(u => u.id === userId);
        
        if (!user) {
            console.log(`用户不存在:${userId}`);
            return {
                success: false,
                data: null as any,
                message: '用户不存在',
                timestamp: new Date().toISOString()
            };
        }
        
        console.log(`找到用户:${user.name}`);
        
        return {
            success: true,
            data: user,
            message: '获取用户成功',
            timestamp: new Date().toISOString()
        };
    }
}

// 📁 src/services/index.ts - 服务入口
export { TaskService } from './taskService';
export { UserService } from './userService';

// 创建服务实例
export const taskService = new TaskService();
export const userService = new UserService();

🔧 工具函数模块

// 📁 src/utils/validation.ts - 验证工具
import type { CreateTaskRequest, CreateUserRequest } from '@types';

export interface ValidationResult {
    isValid: boolean;
    errors: string[];
}

/**
 * 验证任务数据
 * @param task 任务数据
 * @returns 验证结果
 */
export function validateTask(task: CreateTaskRequest): ValidationResult {
    const errors: string[] = [];
    
    console.log('验证任务数据:', task.title);
    
    if (!task.title || task.title.trim().length === 0) {
        errors.push('任务标题不能为空');
    }
    
    if (task.title && task.title.length > 100) {
        errors.push('任务标题不能超过100个字符');
    }
    
    if (!task.description || task.description.trim().length === 0) {
        errors.push('任务描述不能为空');
    }
    
    if (!task.assigneeId || task.assigneeId.trim().length === 0) {
        errors.push('必须指定任务负责人');
    }
    
    if (!['low', 'medium', 'high', 'urgent'].includes(task.priority)) {
        errors.push('任务优先级无效');
    }
    
    if (task.dueDate && task.dueDate < new Date()) {
        errors.push('截止日期不能早于当前时间');
    }
    
    const isValid = errors.length === 0;
    console.log(`任务验证结果:${isValid ? '通过' : '失败'}`);
    
    if (!isValid) {
        console.log('验证错误:', errors);
    }
    
    return { isValid, errors };
}

/**
 * 验证用户数据
 * @param user 用户数据
 * @returns 验证结果
 */
export function validateUser(user: CreateUserRequest): ValidationResult {
    const errors: string[] = [];
    
    console.log('验证用户数据:', user.name);
    
    if (!user.name || user.name.trim().length === 0) {
        errors.push('用户名不能为空');
    }
    
    if (user.name && user.name.length > 50) {
        errors.push('用户名不能超过50个字符');
    }
    
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!user.email || !emailRegex.test(user.email)) {
        errors.push('邮箱格式无效');
    }
    
    if (!['admin', 'manager', 'developer', 'tester'].includes(user.role)) {
        errors.push('用户角色无效');
    }
    
    if (!user.department || user.department.trim().length === 0) {
        errors.push('部门不能为空');
    }
    
    const isValid = errors.length === 0;
    console.log(`用户验证结果:${isValid ? '通过' : '失败'}`);
    
    if (!isValid) {
        console.log('验证错误:', errors);
    }
    
    return { isValid, errors };
}

// 📁 src/utils/formatting.ts - 格式化工具
import type { Task, User, TaskStatus, TaskPriority } from '@types';

/**
 * 格式化日期
 * @param date 日期对象
 * @returns 格式化的日期字符串
 */
export function formatDate(date: Date): string {
    const formatted = date.toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
    });
    
    console.log(`格式化日期:${date.toISOString()} -> ${formatted}`);
    return formatted;
}

/**
 * 格式化任务状态
 * @param status 任务状态
 * @returns 中文状态描述
 */
export function formatTaskStatus(status: TaskStatus): string {
    const statusMap = {
        'pending': '待处理',
        'in-progress': '进行中',
        'completed': '已完成',
        'cancelled': '已取消'
    };
    
    const formatted = statusMap[status] || '未知状态';
    console.log(`格式化任务状态:${status} -> ${formatted}`);
    return formatted;
}

/**
 * 格式化任务优先级
 * @param priority 任务优先级
 * @returns 中文优先级描述
 */
export function formatTaskPriority(priority: TaskPriority): string {
    const priorityMap = {
        'low': '低',
        'medium': '中',
        'high': '高',
        'urgent': '紧急'
    };
    
    const formatted = priorityMap[priority] || '未知优先级';
    console.log(`格式化任务优先级:${priority} -> ${formatted}`);
    return formatted;
}

/**
 * 生成唯一ID
 * @param prefix 前缀
 * @returns 唯一ID
 */
export function generateId(prefix: string = 'id'): string {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substr(2, 8);
    const id = `${prefix}_${timestamp}_${random}`;
    
    console.log(`生成ID:${id}`);
    return id;
}

/**
 * 格式化任务摘要
 * @param task 任务对象
 * @returns 任务摘要字符串
 */
export function formatTaskSummary(task: Task): string {
    const status = formatTaskStatus(task.status);
    const priority = formatTaskPriority(task.priority);
    const dueDate = task.dueDate ? formatDate(task.dueDate) : '无截止日期';
    
    const summary = `[${status}] ${task.title} (优先级:${priority},截止:${dueDate})`;
    console.log(`格式化任务摘要:${summary}`);
    return summary;
}

// 📁 src/utils/index.ts - 工具入口
export * from './validation';
export * from './formatting';

// 通用工具函数
/**
 * 延迟执行
 * @param ms 延迟毫秒数
 * @returns Promise
 */
export function delay(ms: number): Promise<void> {
    console.log(`开始延迟 ${ms}ms`);
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(`延迟 ${ms}ms 完成`);
            resolve();
        }, ms);
    });
}

/**
 * 安全的JSON解析
 * @param jsonString JSON字符串
 * @param defaultValue 默认值
 * @returns 解析结果
 */
export function safeJsonParse<T>(jsonString: string, defaultValue: T): T {
    try {
        const result = JSON.parse(jsonString);
        console.log('JSON解析成功');
        return result;
    } catch (error) {
        console.log('JSON解析失败,使用默认值');
        return defaultValue;
    }
}

🎮 应用入口演示

// 📁 src/app.ts - 应用入口
import { taskService, userService } from '@services';
import { formatTaskSummary, delay } from '@utils';
import type { CreateTaskRequest, CreateUserRequest } from '@types';

console.log('=== 任务管理系统演示 ===');
// "=== 任务管理系统演示 ==="

/**
 * 演示完整的任务管理流程
 */
async function demonstrateTaskManagement() {
    console.log('\n--- 1. 创建用户 ---');
    // "--- 1. 创建用户 ---"
    
    // 创建用户
    const createUserRequest: CreateUserRequest = {
        name: '张三',
        email: 'zhangsan@example.com',
        role: 'developer',
        department: '技术部'
    };
    
    const userResponse = await userService.createUser(createUserRequest);
    // "验证用户数据:张三"
    // "用户验证结果:通过"
    // "生成ID:user_1704067200000_abc12345"
    // "创建新用户:张三"
    // "用户创建成功:user_1704067200000_abc12345"
    // "当前用户总数:1"
    
    if (!userResponse.success) {
        console.error('用户创建失败:', userResponse.message);
        return;
    }
    
    const user = userResponse.data;
    console.log(`用户创建成功:${user.name} (${user.id})`);
    // "用户创建成功:张三 (user_1704067200000_abc12345)"
    
    console.log('\n--- 2. 创建任务 ---');
    // "--- 2. 创建任务 ---"
    
    // 创建任务
    const createTaskRequest: CreateTaskRequest = {
        title: '实现用户登录功能',
        description: '开发用户登录页面,包括表单验证和身份认证',
        priority: 'high',
        assigneeId: user.id,
        dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // 7天后
    };
    
    const taskResponse = await taskService.createTask(createTaskRequest);
    // "验证任务数据:实现用户登录功能"
    // "任务验证结果:通过"
    // "生成ID:task_1704067200001_def67890"
    // "创建新任务:实现用户登录功能"
    // "任务创建成功:task_1704067200001_def67890"
    // "当前任务总数:1"
    
    if (!taskResponse.success) {
        console.error('任务创建失败:', taskResponse.message);
        return;
    }
    
    const task = taskResponse.data;
    console.log(`任务创建成功:${task.title} (${task.id})`);
    // "任务创建成功:实现用户登录功能 (task_1704067200001_def67890)"
    
    // 格式化任务摘要
    const taskSummary = formatTaskSummary(task);
    // "格式化任务状态:pending -> 待处理"
    // "格式化任务优先级:high -> 高"
    // "格式化日期:2024-01-08T12:00:00.000Z -> 2024/01/08"
    // "格式化任务摘要:[待处理] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
    console.log(`任务摘要:${taskSummary}`);
    // "任务摘要:[待处理] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
    
    console.log('\n--- 3. 更新任务状态 ---');
    // "--- 3. 更新任务状态 ---"
    
    // 模拟任务进度
    await delay(1000);
    // "开始延迟 1000ms"
    // (1秒后)
    // "延迟 1000ms 完成"
    
    const updateResponse = await taskService.updateTask(task.id, {
        status: 'in-progress'
    });
    // "更新任务:task_1704067200001_def67890"
    // "更新内容:" { status: 'in-progress' }
    // "任务更新成功:实现用户登录功能"
    
    if (updateResponse.success) {
        const updatedTask = updateResponse.data;
        const updatedSummary = formatTaskSummary(updatedTask);
        // "格式化任务状态:in-progress -> 进行中"
        // "格式化任务优先级:high -> 高"
        // "格式化日期:2024-01-08T12:00:00.000Z -> 2024/01/08"
        // "格式化任务摘要:[进行中] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
        console.log(`任务状态已更新:${updatedSummary}`);
        // "任务状态已更新:[进行中] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
    }
    
    console.log('\n--- 4. 查询任务列表 ---');
    // "--- 4. 查询任务列表 ---"
    
    const tasksResponse = await taskService.getTasks(
        { status: 'in-progress' },
        1,
        5
    );
    // "获取任务列表:页码1,每页5条"
    // "过滤条件:" { status: 'in-progress' }
    // "状态过滤后:1条"
    // "分页结果:第1页,共1页,当前页1条"
    
    if (tasksResponse.success) {
        console.log(`找到 ${tasksResponse.data.length} 个进行中的任务`);
        // "找到 1 个进行中的任务"
        
        tasksResponse.data.forEach((task, index) => {
            const summary = formatTaskSummary(task);
            console.log(`${index + 1}. ${summary}`);
            // "格式化任务状态:in-progress -> 进行中"
            // "格式化任务优先级:high -> 高"
            // "格式化日期:2024-01-08T12:00:00.000Z -> 2024/01/08"
            // "格式化任务摘要:[进行中] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
            // "1. [进行中] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
        });
    }
    
    console.log('\n--- 5. 完成任务 ---');
    // "--- 5. 完成任务 ---"
    
    await delay(2000);
    // "开始延迟 2000ms"
    // (2秒后)
    // "延迟 2000ms 完成"
    
    const completeResponse = await taskService.updateTask(task.id, {
        status: 'completed'
    });
    // "更新任务:task_1704067200001_def67890"
    // "更新内容:" { status: 'completed' }
    // "任务更新成功:实现用户登录功能"
    
    if (completeResponse.success) {
        const completedTask = completeResponse.data;
        const completedSummary = formatTaskSummary(completedTask);
        // "格式化任务状态:completed -> 已完成"
        // "格式化任务优先级:high -> 高"
        // "格式化日期:2024-01-08T12:00:00.000Z -> 2024/01/08"
        // "格式化任务摘要:[已完成] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
        console.log(`任务已完成:${completedSummary}`);
        // "任务已完成:[已完成] 实现用户登录功能 (优先级:高,截止:2024/01/08)"
    }
    
    console.log('\n--- 演示完成 ---');
    // "--- 演示完成 ---"
}

// 运行演示
demonstrateTaskManagement().catch(error => {
    console.error('演示过程中发生错误:', error);
});

🎯 模块化设计的核心收益

设计原则实现方式带来的好处
单一职责每个模块专注特定功能代码清晰,易于维护
依赖注入通过import明确依赖便于测试和替换
类型安全统一的类型定义减少运行时错误
可扩展性模块化的服务层易于添加新功能
可重用性通用的工具函数提高开发效率

📋 本章核心收获

🎯 关键概念掌握

  1. ES模块系统:现代JavaScript的标准模块化方案

    • import/export 语法的灵活运用
    • 动态导入实现按需加载
    • 模块作用域隔离避免全局污染
  2. 命名空间:TypeScript的传统代码组织方式

    • 适用于特定场景(全局脚本、类型声明)
    • 嵌套命名空间实现层次化管理
    • 与现代模块系统的对比选择
  3. 模块解析策略:编译器的"导航系统"

    • Node.js风格的解析算法
    • 路径别名简化导入路径
    • 解析顺序的深入理解
  4. 声明合并:TypeScript的独特功能

    • 接口合并扩展第三方库
    • 命名空间合并组织复杂功能
    • 类与命名空间合并增强静态功能
  5. 三斜线指令:传统的依赖声明方式

    • 在特定场景下的价值
    • 与现代模块系统的迁移策略

🛠️ 实践技能提升

  1. 项目结构设计:合理的目录组织
  2. 类型系统规划:统一的类型定义管理
  3. 服务层架构:模块化的业务逻辑组织
  4. 工具函数封装:可重用的通用功能
  5. 配置文件优化:TypeScript编译选项调优

🎨 设计模式应用

  1. 模块模式:封装和暴露接口
  2. 工厂模式:服务实例的创建管理
  3. 策略模式:不同解析策略的选择
  4. 装饰器模式:功能的渐进式增强

🚀 最佳实践总结

  1. 优先使用ES模块:拥抱现代标准
  2. 合理设计目录结构:便于维护和扩展
  3. 统一类型定义:提高代码一致性
  4. 配置路径别名:简化导入路径
  5. 渐进式迁移:从旧系统平滑过渡

🎯 进阶学习方向

  1. 微前端架构:大型应用的模块化拆分
  2. 模块联邦:跨应用的模块共享
  3. Tree Shaking优化:减少打包体积
  4. 代码分割策略:提升加载性能
  5. 模块热替换:提升开发体验

🎉 恭喜你! 你已经掌握了TypeScript模块化开发的精髓,就像一位经验丰富的城市规划师,能够设计出既美观又实用的代码"城市"。下一章我们将进入装饰器的奇妙世界,学习如何通过装饰器为代码添加"魔法"般的增强功能!