当前位置: 首页 > 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.jsqmd.com/news/861959/

相关文章:

  • 论文AI率爆表怕延毕?5招实测降AI率,3分钟知网AIGC过审上岸
  • 【限时解密】Midjourney后现代风格黄金参数矩阵(含27组实测CR值对比数据):错过本轮更新将永久失去V6.1前最后兼容窗口期
  • Mamba架构原理与工业级长文本处理实战指南
  • 软考高项案例分析1:项目整合管理
  • 郯城本地苗木供应商评测:山东,临沂,江苏,乌桕苗木、巨紫荆苗木、日本红枫苗木、朴树苗木、榉树苗木、樱花苗木、欧洲枫香苗木选择指南 - 优质品牌商家
  • 【ChatGPT】面相工业级FDM/FFF 高温材料成型设备Fortus 450mc / F900的深度拆解、信息图、爆炸图、C++代码框架
  • 熬夜降AI率必看保姆级指南:2026年5月知网维普AI率5%上岸
  • 从 Excel 手算理解 MLP(多层感知机)的完整计算过程
  • 代码大模型训练的典型工程挑战解析
  • 学生用户画像-考勤主题标签构建
  • K8s Ingress Nginx 控制器配置 HTTPS 自动重定向的 YAML 要怎么写?
  • 2026年四川颗粒板厂家评测:靠谱供应商核心维度解析 - 优质品牌商家
  • 卷赢了!山东大学学者七库联合发文一区TOP(IF 10.6),解锁痴呆研究新赛道!
  • Mythos骨架式推理:企业级AI能力治理与因果建模新范式
  • C++静态成员与静态方法
  • 2026年q2天津闲置酒水回收正规机构实力盘点:天津名贵酒品回收回收/天津洋酒回收/天津礼盒酒水回收/优选推荐 - 优质品牌商家
  • Transformer架构优化与高效计算实践
  • C++强制类型转换的四种方式
  • 国内不发火水泥砂浆高性价比厂家实测排行权威盘点:环氧灌浆料/环氧砂浆/环氧胶泥/硅烷浸渍剂/硅烷膏体/优选指南 - 优质品牌商家
  • 【助睿实验指导】助睿ETL-订单利润分流数据加工
  • 台湾话TTS自然度卡在3.2/5?用MOS-LQO双维度测评法定位8类发音失真源(附自动化诊断脚本)
  • 预测性线索评分:用机器学习提升B2B销售转化率的实战指南
  • 警惕AI领域未经证实的技术传闻与虚构命名
  • 留学生遭遇大厂 PIP 晴天霹雳?2026 北美科技圈绩效提升计划深度解码与生存闭环
  • CAN模型:让GAN具备审美判断与风格突破能力
  • 智慧铁路之钢轨缺陷识别 自动化轨道检测系统开发 铁路养护车辆计算机视觉功能实现 轨道交通腐蚀识别 钢轨磨损识别10340期
  • LeetCode--112. 路径总和(二叉树)
  • 动态图神经网络实现多商品时序协同预测
  • 大模型技能训练:从模仿到自主进化
  • 千问 LeetCode 2532.过桥的时间 public int findCrossingTime(int n, int k, int[][] time)