第八章-模块与命名空间
第八章模块与命名空间模块TypeScript 模块是自包含的代码单元每个模块都有自己的作用域。模块中的变量、函数、类等默认是私有的需要显式导出才能被其他模块使用。导出使用export关键字导出模块中的成员// 导出常量exportconstPI3.14159;// 导出函数exportfunctioncalculateCircleArea(radius:number):number{returnPI*radius*radius;}// 导出类exportclassCalculator{add(a:number,b:number):number{returnab;}subtract(a:number,b:number):number{returna-b;}}导入使用import关键字导入其他模块的成员// 命名导入import{PI,calculateCircleArea}from./math;import{Calculator}from./calculator;// 命名空间导入import*asMathUtilsfrom./math;// 使用导入的成员constareacalculateCircleArea(5);constcalcnewCalculator();constsumcalc.add(1,2);默认导出每个模块只能有一个默认导出// 默认导出类exportdefaultclassStringUtils{statictoUpperCase(str:string):string{returnstr.toUpperCase();}statictoLowerCase(str:string):string{returnstr.toLowerCase();}}// 导入默认导出importStringUtilsfrom./string-utils;重新导出模块可以重新导出其他模块的成员// 重新导出特定成员export{PI,calculateCircleArea}from./math;export{Calculator}from./calculator;// 重命名后重新导出export{defaultasStringUtils}from./string-utils;// 重新导出整个模块export*from./utils;命名空间命名空间Namespace是 TypeScript 提供的一种组织代码的方式用于避免全局作用域污染。在现代 TypeScript 开发中推荐使用模块而不是命名空间。定义命名空间namespaceMyNamespace{exportconstVERSION1.0.0;exportfunctiongreet(name:string):string{returnHello,${name}!;}exportclassUser{constructor(privatename:string){}getName():string{returnthis.name;}}}// 使用命名空间console.log(MyNamespace.VERSION);console.log(MyNamespace.greet(Alice));constusernewMyNamespace.User(Bob);嵌套命名空间namespaceApp{exportnamespaceUtils{exportfunctionformatDate(date:Date):string{returndate.toISOString();}}exportnamespaceServices{exportclassUserService{getUser(id:number){return{id,name:Alice};}}}}// 使用嵌套命名空间App.Utils.formatDate(newDate());constuserServicenewApp.Services.UserService();跨文件命名空间命名空间可以跨越多个文件// animal.tsnamespaceAnimals{exportclassDog{bark(){console.log(Woof!);}}}// main.ts/// reference pathanimal.ts /namespaceAnimals{exportclassCat{meow(){console.log(Meow!);}}}constdognewAnimals.Dog();constcatnewAnimals.Cat();类型导入TypeScript 3.8 支持类型导入类型导入在编译时会被完全删除// 类型导入importtype{User}from./user;// 混合导入值和类型import{typeUser,typeProduct,calculateTotal}from./types;动态导入动态导入允许在运行时按需加载模块asyncfunctionloadModule(){constmoduleawaitimport(./calculator);constcalcnewmodule.Calculator();returncalc.add(1,2);}// 使用动态导入loadModule().then(result{console.log(result);// 3});import() 类型可以使用import()作为类型注解typeModuleTypetypeofimport(./calculator);模块 vs 命名空间特性模块命名空间作用域文件作用域命名空间作用域依赖ES Module///打包支持现代打包工具需要特殊处理推荐✅ 推荐⚠️ 仅限特定场景类型安全✅ 完全支持✅ 完全支持最佳实践优先使用模块现代 TypeScript 项目推荐使用 ES 模块使用类型导入对于仅用于类型的导入使用import type合理使用动态导入用于代码分割和按需加载避免全局命名空间减少全局作用域污染保持模块小而专注每个模块应该有单一职责使用明确的导入路径避免使用相对路径的复杂嵌套重新导出公共 API为库提供清晰的公共接口