当前位置: 首页 > news >正文

13. 模块系统

13. 模块系统

1. 概述

TypeScript 模块系统基于 ECMAScript 模块(ESM)标准,支持代码的组织、封装和复用。模块是 TypeScript 组织代码的基本单位,每个文件都是一个独立的模块。

┌─────────────────────────────────────────────────────────────┐ │ TypeScript 模块系统 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 模块导出 │ │ ├── 命名导出:`export const name = value`│ │ ├── 默认导出:`export default value`│ │ ├── 批量导出:`export { name1, name2 }`│ │ ├── 重命名导出:`export { name as alias }`│ │ └── 类型导出:`export type { Type }`│ │ │ │ 模块导入 │ │ ├── 命名导入:`import { name } from './module'`│ │ ├── 默认导入:`import name from './module'`│ │ ├── 混合导入:`import name, { other } from './module'`│ │ ├── 命名空间导入:`import * as ns from './module'`│ │ ├── 类型导入:`import type { Type } from './module'`│ │ └── 动态导入:`const module = await import('./module')`│ │ │ │ 模块解析策略 │ │ ├── Classic:传统 TypeScript 解析 │ │ ├── Node:Node.js 模块解析 │ │ └── Bundler:打包器解析(TypeScript5.0+) │ │ │ └─────────────────────────────────────────────────────────────┘

2. 导出(Export)

2.1 命名导出

// math.ts// 单独导出exportconstPI=3.14159;exportconstE=2.71828;exportfunctionadd(a:number,b:number):number{returna+b;}exportclassCalculator{multiply(a:number,b:number):number{returna*b;}}// 批量导出constsubtract=(a:number,b:number)=>a-b;constdivide=(a:number,b:number)=>a/b;export{subtract,divide};// 重命名导出export{subtractassub,divideasdiv};

2.2 默认导出

// logger.ts// 单个默认导出constlogger={info:(msg:string)=>console.log(`[INFO]${msg}`),error:(msg:string)=>console.error(`[ERROR]${msg}`),warn:(msg:string)=>console.warn(`[WARN]${msg}`)};exportdefaultlogger;// 函数默认导出exportdefaultfunctiongreet(name:string):string{return`Hello,${name}!`;}// 类默认导出exportdefaultclassUser{constructor(publicname:string,publicage:number){}}

2.3 类型导出

// types.ts// 类型别名导出exporttypeUserID=string|number;exporttypeStatus='pending'|'active'|'inactive';// 接口导出exportinterfaceUser{id:UserID;name:string;email:string;status:Status;}// 类型和值混合导出exportconstDEFAULT_USER:User={id:'guest',name:'Guest',email:'guest@example.com',status:'active'};// 使用 export type 明确导出类型exporttype{UserasUserType};

3. 导入(Import)

3.1 命名导入

// app.ts// 导入命名导出import{PI,E,add,Calculator}from'./math';console.log(PI);// 3.14159console.log(add(5,3));// 8constcalc=newCalculator();console.log(calc.multiply(4,5));// 20// 导入重命名的导出import{sub,div}from'./math';console.log(sub(10,3));// 7console.log(div(10,2));// 5// 导入时重命名import{addasaddNumbers}from'./math';console.log(addNumbers(1,2));

3.2 默认导入

// 导入默认导出importloggerfrom'./logger';importgreetfrom'./logger';importUserfrom'./logger';logger.info('Application started');console.log(greet('Alice'));constuser=newUser('Bob',30);// 默认导入可以任意命名importmyLoggerfrom'./logger';myLogger.info('Using custom name');

3.3 混合导入

// 同时导入默认和命名导出importlogger,{LogLevel,formatMessage}from'./logger';// 导入默认和所有命名导出importlogger,*asloggingfrom'./logger';

3.4 命名空间导入

// 将所有导出导入为一个对象import*asMathUtilsfrom'./math';console.log(MathUtils.PI);// 3.14159console.log(MathUtils.add(5,3));// 8console.log(MathUtils.sub(10,4));// 6constcalc=newMathUtils.Calculator();console.log(calc.multiply(3,4));// 12

3.5 类型导入

// 只导入类型(不导入值)importtype{User,Status}from'./types';// 混合导入值和类型import{DEFAULT_USER,typeUser}from'./types';constuser:User={id:1,name:'Alice',email:'alice@example.com',status:'active'};console.log(DEFAULT_USER);

4. 动态导入

4.1 基本用法

// 动态导入返回 PromiseasyncfunctionloadModule(){constmath=awaitimport('./math');console.log(math.add(5,3));}// 条件加载asyncfunctionloadFeature(featureName:string){if(featureName==='chart'){constchart=awaitimport('./chart');chart.render();}elseif(featureName==='table'){consttable=awaitimport('./table');table.display();}}// 动态导入类型asyncfunctionloadTypes(){constmodule=awaitimport('./types');typeUser=module.User;}

4.2 React 懒加载

// React 组件懒加载import{lazy,Suspense}from'react';constDashboard=lazy(()=>import('./Dashboard'));constProfile=lazy(()=>import('./Profile'));functionApp(){return(<Suspense fallback={<div>Loading...</div>}><Dashboard/></Suspense>);}

5. 模块解析

5.1 相对路径 vs 绝对路径

// 相对路径(相对于当前文件)import{helper}from'./utils/helper';import{config}from'../config';// 绝对路径(基于 baseUrl)import{helper}from'utils/helper';import{config}from'config';// 路径映射(paths 配置)import{UserService}from'@services/user';import{formatDate}from'@utils/date';

5.2 路径映射配置

// tsconfig.json{"compilerOptions":{"baseUrl":".","paths":{"@/*":["src/*"],"@components/*":["src/components/*"],"@utils/*":["src/utils/*"],"@services/*":["src/services/*"]}}}
// 使用路径映射importButtonfrom'@components/Button';import{formatDate}from'@utils/date';import{UserService}from'@services/UserService';

6. 命名空间(Namespace)

虽然命名空间在模块化时代已经不推荐使用,但了解其语法有助于阅读旧代码。

// namespace.tsnamespaceValidation{exportinterfaceStringValidator{isAcceptable(s:string):boolean;}exportclassEmailValidatorimplementsStringValidator{isAcceptable(s:string):boolean{return/@/.test(s);}}exportclassPhoneValidatorimplementsStringValidator{isAcceptable(s:string):boolean{return/\d{11}/.test(s);}}}// 使用命名空间constemailValidator=newValidation.EmailValidator();console.log(emailValidator.isAcceptable('test@example.com'));// true// 命名空间可以跨文件合并// 推荐使用模块代替命名空间

7. 三斜线指令

三斜线指令用于在旧代码中引用依赖,现代 TypeScript 项目推荐使用 ES 模块。

/// <reference path="../types/global.d.ts" />/// <reference types="node" />/// <reference lib="dom" />// 使用全局类型constelement:HTMLElement=document.getElementById('app');

8. 完整示例:模块化应用

// ============ 1. 类型定义模块 ============// types/user.tsexportinterfaceUser{id:number;name:string;email:string;createdAt:Date;}exporttypeUserCreateInput=Omit<User,'id'|'createdAt'>;exporttypeUserUpdateInput=Partial<Omit<User,'id'>>;// ============ 2. 服务模块 ============// services/userService.tsimporttype{User,UserCreateInput,UserUpdateInput}from'../types/user';exportclassUserService{privateusers:Map<number,User>=newMap();privatenextId:number=1;asynccreate(data:UserCreateInput):Promise<User>{constuser:User={id:this.nextId++,...data,createdAt:newDate()};this.users.set(user.id,user);returnuser;}asyncfindById(id:number):Promise<User|null>{returnthis.users.get(id)||null;}asyncfindAll():Promise<User[]>{returnArray.from(this.users.values());}asyncupdate(id:number,data:UserUpdateInput):Promise<User|null>{constuser=this.users.get(id);if(!user)returnnull;constupdated={...user,...data};this.users.set(id,updated);returnupdated;}asyncdelete(id:number):Promise<boolean>{returnthis.users.delete(id);}}exportconstuserService=newUserService();// ============ 3. 工具模块 ============// utils/validation.tsexportfunctionvalidateEmail(email:string):boolean{constemailRegex=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;returnemailRegex.test(email);}exportfunctionvalidateName(name:string):boolean{returnname.length>=2&&name.length<=50;}exportfunctionformatDate(date:Date):string{returndate.toLocaleDateString('zh-CN');}// ============ 4. 控制器模块 ============// controllers/userController.tsimport{userService}from'../services/userService';import{validateEmail,validateName,formatDate}from'../utils/validation';importtype{UserCreateInput}from'../types/user';exportclassUserController{asynccreateUser(req:{body:UserCreateInput}){const{name,email}=req.body;if(!validateName(name)){return{success:false,error:'Invalid name'};}if(!validateEmail(email)){return{success:false,error:'Invalid email'};}constuser=awaituserService.create(req.body);return{success:true,data:user};}asyncgetUser(id:number){constuser=awaituserService.findById(id);if(!user){return{success:false,error:'User not found'};}return{success:true,data:{...user,formattedDate:formatDate(user.createdAt)}};}}// ============ 5. 主入口模块 ============// index.tsimport{UserController}from'./controllers/userController';import{userService}from'./services/userService';asyncfunctionmain(){constcontroller=newUserController();// 创建用户constcreateResult=awaitcontroller.createUser({body:{name:'Alice',email:'alice@example.com'}});console.log('Create result:',createResult);// 获取用户if(createResult.success&&createResult.data){constgetUserResult=awaitcontroller.getUser(createResult.data.id);console.log('Get user result:',getUserResult);}// 列出所有用户constusers=awaituserService.findAll();console.log('All users:',users);}main().catch(console.error);

9. 模块解析策略

策略说明适用场景
classicTypeScript 原始解析方式已废弃,不推荐
nodeNode.js 模块解析Node.js 项目
bundler打包器解析(TS 5.0+)前端项目(Vite、Webpack)
nodenextNode.js 最新解析Node.js ESM 项目
// tsconfig.json{"compilerOptions":{"module":"ESNext","moduleResolution":"bundler","esModuleInterop":true,"allowSyntheticDefaultImports":true,"resolveJsonModule":true}}

10. 总结

导出方式语法导入语法
命名导出export const x = 1import { x }
默认导出export default ximport x
批量导出export { a, b }import { a, b }
重命名导出export { a as b }import { b }
类型导出export type T = ...import type { T }
命名空间导入import * as nsns.x
动态导入await import()Promise 异步

http://www.cnnetsun.cn/news/2502910.html

相关文章:

  • 太突然!IPO紧要关头,Karpathy加入Anthropic
  • 探索C/C++程序从源码到可执行文件的编译之旅
  • 嘉立创EDA:原理图到PCB学习总结
  • 用Claude Code做了一件事,现在AI比我还了解我?
  • CVPR 2026 预讲会54位讲者云集| 6大方向+5个专场
  • 留学生遭遇大厂 PIP 晴天霹雳?2026 北美科技圈绩效提升计划深度解码与生存闭环
  • 多代理RTL漏洞检测系统:原理、实践与优化
  • 离子原生QAOA算法:量子优化新突破
  • AI Agent Runtime 正在成为新基础设施层
  • Multi-Head Latent Attention(MLA)原理与工程实践全解析
  • 机器学习评估指标实战指南:业务、数据与工程的决策逻辑
  • Neural Code Search:代码语义搜索原理与工程落地
  • 激活函数为什么是神经网络的非线性开关?
  • Determined AI分布式训练实战:突破算法与编码偏差治理
  • MoE混合专家架构原理与工程实践:解密大模型稀疏计算真相
  • 2026年5月降AI率保姆级避坑指南:知网维普AI率5%上岸
  • GPT-4参数真相:1.8万亿与2%稀疏激活的技术本质
  • TensorFlow 2迁移学习实战:图像分类快速上手指南
  • VMPDump:突破性动态脱壳与智能导入表修复技术方案
  • 【从零到一】一篇文章让你彻底玩转Spearman相关性矩阵
  • Cloud-Device Collaborative Learning for Multimodal Large Language Models
  • Sa-Token客户端ID校验失败的原理与修复指南
  • OpenSSH 9.6p1紧急升级全解析:CVE-2023-51385漏洞修复实战指南
  • Unity对象池架构设计:从状态管理到Reset三级清洗
  • Unity多分辨率UI适配原理与Resize Pro动态缩放实战
  • OpenAI投2.34亿美元、谷歌携多项计划,新加坡AI战略引科技巨头入局
  • UE5 Windows到Linux交叉编译避坑指南:ABI兼容与构建链路实战
  • Unity编辑器资源创建性能优化:从Prefab到场景的序列化治理
  • 中国分县林地面积统计数据
  • 技术选型翻车实录:我们选的那个框架,两年后停止维护了