TypeScript 命名空间和模块

如何理解 TypeScript 中命名空间与模块?两者都有那些区别?如何更好的应用? 在 TypeScript 中,(Namespace)和(Module)是两种不同的代码组织方式,用于组织和管理代码结构,避免命名冲突和提高可维护性。虽然它们都可以将代码划分为不同的逻辑单元,但在使用上有一些区别。 阅读详情

介绍

TypeScript 1.5里术语名已经发生了变化:

  • “内部模块”现在称做“命名空间”。也就是说像 module X { } 这样的写法,在当前推荐的写法中应该是 namespace X { } 。

  • “外部模块”现在简称为“模块”,通常通过 import 和 export 关键字来实现模块间的功能共享和代码组织。

这是为了让 TypeScript 与 ECMAScript 2015(ES6)的术语保持一致,从而减少混淆并提高与主流 JavaScript 标准的兼容性。

命名空间

命名空间(Namespace)用于组织和封装相关的代码,以避免全局命名冲突,并提供更好的代码结构和模块化。

  • 基本语法
    • 使用 namespace 关键字来创建命名空间
  • 成员
    • 命名空间可以包含以下类型的成员:变量、函数、类、接口

示例:

namespace MathUtils {
  // 要使命名空间中的成员在外部可访问,需要使用 export 关键字
  export function add(a: number, b: number): number {
    return a + b;
  }

  export function subtract(a: number, b: number): number {
    return a - b;
  }
}

// 使用命名空间中的函数
let result1 = MathUtils.add(5, 3);
let result2 = MathUtils.subtract(8, 2);
console.log(result1, result2); // 8  6

在上述代码中,MathUtils 是一个命名空间,其中包含了 add 和 subtract 两个函数。通过 namespace 关键字创建了这个命名空间,并使用 export 关键字使其中的函数可以在命名空间外部被访问。

可以在不同的位置多次定义同一个命名空间,TypeScript 会将它们的成员进行合并:

namespace MyNamespace {
  export function function1() {
    // 实现
  }
}

namespace MyNamespace {
  export function function2() {
    // 实现
  }
}

多文件中的命名空间

当涉及到多个文件中的命名空间时,要使命名空间中的成员在外部可访问,需要使用 export 关键字和 import 关键字。

假设我们有两个文件:file1.ts 和 file2.ts
file1.ts:

export namespace MyNamespace {
  export function function1() {
    console.log('Function 1 in MyNamespace');
  }
}

file2.ts:

export namespace MyNamespace {
  export function function2() {
    console.log('Function 2 in MyNamespace');
  }
}

在另一个文件 main.ts 中使用 :

import { MyNamespace } from './file1';
import { MyNamespace } from './file2';

MyNamespace.function1();
MyNamespace.function2();

在 file1.ts 和 file2.ts 中使用 export 关键字导出相关的内容,然后在需要使用的文件(如 main.ts)中使用 import 语句来引入。

别名

使用 import q = x.y.z 的方式给命名空间中的对象创建别名,来简化命名空间的操作。

还可以用这种方法为任意标识符创建别名,也包括导入的模块中的对象。

首先,创建一个包含命名空间的文件 namespaceFile.ts:

namespace MyComplexNamespace {
  export namespace SubNamespace {
    export function SomeFunction() {
      console.log('This is a function in the namespace.');
    }
  }
}

然后,在另一个文件 main.ts 中使用别名来简化对命名空间中函数的调用:

import q = MyComplexNamespace.SubNamespace.SomeFunction;

q();

通过 import q = MyComplexNamespace.SubNamespace.SomeFunction; 给命名空间中的函数 SomeFunction 起了一个短别名 q,然后在后续的代码中直接使用 q() 来调用该函数,而无需再写完整的命名空间路径。

注意:没有使用require关键字,而是直接使用导入符号的限定名赋值。

当使用直接使用导入符号的限定名进行赋值来创建别名时:

import q = MyComplexNamespace.SubNamespace.SomeFunction;

这类似于使用 var 来创建变量,但有一些重要的区别:

  • 适用于类型和具有命名空间含义的符号: 不仅可以用于普通的值,还可以用于类型、命名空间等。
  • 对于值,创建的是新的引用: 这意味着对别名所做的修改不会影响原始导入的值。

例如:

// originalModule.ts
export let originalValue = 10;

// main.ts
import MyValue = originalModule.originalValue;

// 修改 MyValue 的值,不影响原始数据
MyValue = 20; 
console.log(originalModule.originalValue); // 仍然是 10,没有被修改

模块

在 TypeScript 中,“外部模块”简称为“模块”。

模块是用于组织和封装代码的重要机制。模块可以将相关的功能分组到独立的单元中,具有更好的可维护性、可复用性和可测试性。

模块中的变量、函数、类等成员具有模块级别的作用域,不会污染全局作用域。

  • 定义在一个模块里的变量,函数,类等等在模块外部是不可见的。除非使用export 关键字明确导出它们。
  • 如果想使用其它模块导出的变量,函数,类,接口等的时候,必须要使用import 关键字导入它们,

模块是自声明的;两个模块之间的关系是通过在文件级别上使用imports和exports建立的。

模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。

导出

使用 export 关键字导出模块的成员,使其可以在其他模块中被访问。

任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加export关键字来导出:

export function myFunction() {
  // 函数实现
}
export class MyClass {
  // 类的定义
}
export interface StringValidator {
  // 接口的定义
  isAcceptable(s: string): boolean;
}
export class ZipCodeValidator implements StringValidator {
  isAcceptable(s: string) {
    // 具体实现
  }
}

导出可以重命名:

export { ZipCodeValidator as mainValidator };

默认导出

每个模块都可以有一个默认导出, 默认导出使用 default关键字标记。
一个模块只能够有一个default导出。
导入默认导出时可以使用任何名称。

// file1.ts  类作为默认导出
export default class MyDefaultClass {
  // 类的实现
}

// file2.ts  变量作为默认导出
export default const myDefaultVariable = 10;

// myModule.ts
// 函数作为默认导出
export default function myDefaultFunction() {
  // 函数实现
}

// other.ts 中导入
import myDefaultFunctionfrom './myModule'; 
// 导入并将其命名
import anotherName from './myModule';

导入

使用 import 关键字从其他模块导入需要的成员。
可以使用相对路径(如 ./myModule )或绝对路径(如 @myModule ,需要配置路径别名)来导入模块。

import { ZipCodeValidator } from "./ZipCodeValidator";
let myValidator = new ZipCodeValidator();

可以对导入内容重命名:

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

将整个模块导入到一个变量,并通过它来访问模块的导出部分:

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

具有副作用的导入模块
尽管不推荐这么做,一些模块会设置一些全局状态供其它模块使用。 这些模块可能没有任何的导出或用户根本就不关注它的导出。 使用下面的方法来导入这类模块:

import "./my-module.js";

当使用 import 来引用模块时,TypeScript 编译器会按照特定的规则来查找模块的类型信息。
它会首先在指定的路径下查找 .ts、.tsx 或 .d.ts 文件。如果这些文件都不存在,编译器就会去查找外部模块声明,这些声明通常在 .d.ts 文件中。
import 提供了更明确和可靠的模块引用方式,它清晰地表明了模块之间的依赖关系。

export = 和 import = require()

CommonJS和AMD的环境里都有一个exports变量,这个变量包含了一个模块的所有导出内容。

CommonJS和AMD的exports都可以被赋值为一个对象, 这种情况下其作用就类似于 es6 语法里的默认导出,即 export default语法了。虽然作用相似,但是 export default 语法并不能兼容CommonJS和AMD的exports。

为了支持CommonJS和AMD的exports, TypeScript提供了export =语法。

export =语法定义一个模块的导出对象。 这里的对象一词指的是类,接口,命名空间,函数或枚举。

若使用export =导出一个模块,则必须使用TypeScript的特定语法import module = require("module")来导入此模块。

export = 用于将模块的默认导出设置为一个特定的值或对象:

// myModule.ts
class MyClass {
  // 类的实现
}

export = MyClass;

import = require() 用于从使用 export = 导出的模块中导入默认导出:

// other.ts
import myModule = require('./myModule');

这种语法在将基于 CommonJS 风格的模块集成到 TypeScript 项目中时可能会用到,但在现代 TypeScript 开发中,更推荐使用基于 ES6 模块的 import 和 export 语法,因为它们更符合现代 JavaScript 的标准和趋势。
例如,使用 ES6 模块的对应方式可能是:

// myModule.ts 导出
export default class MyClass {
  // 类的实现
}

// other.ts 导入
import myModule from './myModule';

命名空间和模块的陷阱

对模块使用/// <reference>

一个常见的错误是使用/// <reference>引用模块文件,应该使用import。
使用 /// <reference> 来引用一个模块文件,当模块文件的位置发生变化或者项目的结构有所调整时,可能会导致引用失败或者出现难以预料的错误。

TypeScript基础知识:模块化和命名空间 模块化在现代的软件开发中,模块化和命名空间是构建可维护、可扩展和可重用代码的关键概念。TypeScript提供了强大的支持来帮助我们组织和管理代码,本文将深入探讨TypeScript中的模块化和命名空间,并提供示例代码来帮助读者更好地理解这些概念。 阅读详情

相关推荐

TypeScript 中的命名空间与模块:深入解析与最佳实践

在 TypeScript 开发中,代码组织是一个至关重要的课题。随着项目规模的扩大,如何有效地管理代码结构、避免命名冲突以及实现清晰的依赖关系变得尤为重要。TypeScript 提供了两种主要的代码组织机制:命名空间(Namespaces)和模块(Modules)。本文将深入探讨这两种机制的区别、适用场景以及最佳实践,帮助开发者做出合理的选择。

vvilkin的学习备忘 1489

typescript中的namespace和modules(译)

介绍 这篇文章概述了多种在typescript中,使用namespaces和modules组织代码的方式,我们将会重温一些进阶的如何使用namespaces和modules的主题,还有处理一些在typescript中使用它们时的一些陷阱 使用Namespaces Namespaces简化了js对象在全局命名空间里的命名,这使得namespaces可以很容易的去构造使用。它们可以跨越多个文件,也可以...

weixin_33686714的博客 3137

Windows下Python多版本共存与切换的终极指南(含环境变量详解)

本文详细解析了在Windows系统下实现Python多版本共存与切换的完整方案。通过深入讲解环境变量Path的底层机制,提供了从安装策略、精细化Path管理到创建快速切换脚本的实战指南,并介绍了py启动器和虚拟环境等高级技巧,帮助开发者彻底解决版本冲突问题,提升开发效率。

v6b7n8m9q0的博客 538

TypeScript基础知识(八)模块和命名空间

*命名空间可以将相关的代码封装在一个独立的作用域中,避免全局命名冲突。当我们在 TypeScript 中使用命名空间(namespace)时,我们可以将相关的代码组织到一个逻辑单元中,以避免全局命名冲突。这些是一些基本的 TypeScript 命名空间的代码案例,它们展示了如何定义和使用命名空间以及如何组织和调用其中的函数。使用命名空间可以将相关的代码组织在一起,提高了代码的可读性和可维护性。然后我们在全局作用域中使用了该命名空间中的代码,创建了一个。在上面的代码中,我们定义了一个命名空间。

青轩桃李能几何,流光欺人忽蹉跎 544

Ansys口腔正畸有限元分析:从几何处理到接触设定的全流程解析

本文详细解析了Ansys在口腔正畸有限元分析中的全流程应用,从几何处理到接触设定,帮助医生精准预测牙齿移动趋势。通过有限元建模技术,可同时观察牙齿-牙周膜-牙槽骨的力学响应,显著提升矫治效果预测准确率。文章还分享了实用技巧和参数设置建议,适用于正畸医生和工程师。

weixin_30897233的博客 348

Cadence ADE实战:1GHz VCO相位噪声仿真全流程(附PSS/Pnoise避坑指南)

本文详细介绍了在Cadence ADE环境中对1GHz VCO进行相位噪声仿真的完整流程。重点剖析了PSS(周期性稳态分析)和Pnoise(周期性噪声分析)两大核心引擎的关键参数设置与避坑指南,帮助射频与模拟IC设计者准确评估VCO性能,解决仿真不收敛、结果异常等常见问题。

rock5的博客 672

【TS】TypeScript namespace和module

namespace 主要用于解决命名冲突,他会在全局生成一个对象,在 namepace 内部的成员都要通过这个对象访问。使用命名空间可以解决代码和第三方库之间的同名冲突。 TS 支持 CommonJS 和 ESM 两种模块系统,使得声明模块有两种写法,分别是使用字符串和变量名 。

zhonggee的博客 955

实战指南:轻松破解DataDome滑块验证码的关键步骤

本文详细介绍了破解DataDome滑块验证码的关键步骤,包括理解其工作原理、准备工作、参数获取与配置、完整破解流程及API调用。通过使用Capsolver服务和模拟真实用户行为,帮助开发者有效绕过这一反机器人机制,同时强调了法律与道德考量。

weixin_30415113的博客 483

TypeScript中的模块与命名空间

在TypeScript中,命名空间(namespace)是用来组织和管理代码的一种方式。它提供了一种将相关的代码分组、隔离和导出的机制,避免了全局命名冲突的问题。命名空间的使用通过namespace关键字来定义,可以在一个文件中定义多个命名空间,并且可以嵌套使用。命名空间中可以包含类、函数、接口和其他命名空间。// 输出: 78.53981633974483 const rectangle = new Shapes . Rectangle("Rectangle" , 3 , 4);

jieyucx的博客 1880

Ubuntu22.04 上ROS1 Noetic的安装与常见问题解决

本文详细介绍了在Ubuntu 22.04系统上安装ROS1 Noetic的两种主要方法:推荐使用社区维护的适配仓库进行便捷安装,并提供了从源码编译的备选方案。文章重点解决了安装后编译ROS包时极易遇到的“shared_mutex”等C++标准库冲突问题,并给出了其他常见错误的排查与解决指南,帮助开发者顺利搭建稳定的ROS开发环境。

weixin_29295541的博客 364

Virtualbox “Kernel driver not installed (rc=-1908)”问题全面解析与修复指南

本文全面解析了Virtualbox出现'Kernel driver not installed (rc=-1908)'错误的原因及修复方法。详细介绍了如何通过重新安装virtualbox-dkms、处理Secure Boot特殊情况等步骤解决该问题,并提供了预防措施与最佳实践,帮助用户避免类似错误再次发生。

weixin_30352645的博客 530

typescript模块与命名空间

从ECMAScript 2015开始,JavaScript引入了模块的概念。TypeScript 也沿用这个概念。模块在其自身的作用域里执行,而不是在全局作用域里;这意味着定义在一个模块里的 变量,函数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出它们。相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用import形式之一。模块是自声明的;两个模块之间的关系是通过在文件级别上使用imports和exports建立的。

wubeidangziqiang的博客 864

运放+MOS恒流源电路仿真分析

利用运放设计一个恒流源

HW-BASE的博客 4097

TypeScript 命名空间与TypeScript 模块

一、TypeScript 命名空间 1.TypeScript 命名空间创建和简单使用 2.嵌套命名空间的简单使用 二、TypeScript 模块 1.TypeScript 模块创建和简单使用

samxiaoguai的博客 887

内容创作全流程自动化:OpenClaw+大模型搞定选题+写稿+多平台发布

本文介绍了一套基于OpenClaw的全自动化内容创作流水线方案,帮助垂直领域创作者摆脱重复劳动。该方案将内容生产拆解为选题生成、内容撰写、格式适配、多平台发布四个模块,通过工作流引擎串联执行。系统能自动采集热榜生成选题、调用大模型撰写结构化内容、适配不同平台格式要求,并通过API+浏览器自动化实现多平台发布,全程只需人工最终审核。作者分享了各模块的实现细节,包括热榜采集、内容结构化生成、Markdown转换和发布策略,并提供了工作流编排方法。这套方案能为创作者每天节省约3小时,同时保证内容质量和发布效率。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 49

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

TypeScript:命名空间和模块

命名空间是位于全局命名空间下的一个普通的带有名字的JavaScript对象。 这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过 --outFile结合在一起。 命名空间是帮你组织Web应用不错的方式

ChinaDragon10的博客 1180

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

TypeScript 命名空间和模块

介绍 这篇文章将概括介绍在TypeScript里使用模块与命名空间来组织代码的方法。 我们也会谈及命名空间和模块的高级使用场景,和在使用它们的过程中常见的陷阱。 查看模块章节了解关于模块的更多信息。 查看命名空间章节了解关于命名空间的更多信息。 使用命名空间 命名空间是位于全局命名空间下的一个普通的带有名字的JavaScript对象。 这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过...

xiaomifeng_li的博客 583

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

TypeScript 中命名空间与模块的区别

TypeScript 与 ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块;相反地,如果一个文件不带有顶级的import或者export声明,那么它的内容被视为全局可见的;

夏天的博客 993

TypeScript 教程(七):模块与命名空间

在前几章中,我们学习了 TypeScript 的基础知识、函数与对象类型、接口与类、以及泛型编程。在本章中,我们将深入探讨 TypeScript 中的模块与命名空间。模块和命名空间是组织代码的两种主要方式,它们有助于代码的模块化和重用性。TS 入门(一):TypeScript 简介与安装TS 入门(二):Typescript类型与类型注解TS 入门(三):Typescript函数与对象类型TS 入门(四):TypeScript 高级类型与类型操作TS 入门(五):TypeScript接口与类。

前端探索者 2284

TypeScript模块(外部模块)、命名空间(内部模块)

模块 关于数据的一点说明:TypeScript 1.5里术语已经发生了变化,“内部模块”现在称作“命名空间”。 “外部模块”现在简称为“模块” 模块在其自身的作用域里执行,而不是在全局作用域里; 这意味着定义一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出他们。 相反,如果想使用其他模块导出的变量,函数,类,接口等的时候,你必须要导入他们,可以使用import形式之一。 假设创建一个db.ts的文件,那么它就是一个模块 export var tes.

土豆牛肉拌面 1630

【TypeScript】命名空间、模块、声明文件

本文详细介绍了TypeScript命名空间、TypeScript模块、TypeScript声明文件的

m0_64455070的博客 1472

TypeScript 中命名空间与模块的理解及区别

命名空间是 TypeScript 中的一个组织代码的方式,主要用于解决全局作用域下的命名冲突问题。通过命名空间,我们可以将相关的代码组织在一起,并且避免了全局污染。模块的特点是它有自己的作用域,这意味着模块内的变量、函数、类等都是局部于该模块的,不会影响到全局作用域。要在外部访问命名空间内的类和接口,我们需要在它们前面加上。,TypeScript 编译器会报错,提示变量重复声明。如果我们没有使用模块系统,而是在另一个文件中也声明了。在 TypeScript 中,我们使用。在 TypeScript 中,

全栈若城,专注知识分享 6万+

TypeScript基础入门之命名空间和模块

转载TypeScript基础入门之命名空间和模块 命名空间和模块 关于术语的说明:值得注意的是,在TypeScript 1.5中,命名法已经改变。 "内部模块"现在是"命名空间"。 "外部模块"现在只是"模块",以便与ECMAScript 2015的术语保持一致(即module X {相当于现在首选的namespace X {)。 介绍 本文概述了使用TypeScript中的命名空间和模块...

zhangda89的专栏 1092

【TypeScript系列】命名空间和模块

这篇文章将概括介绍在TypeScript里使用模块与命名空间来组织代码的方法。 我们也会谈及命名空间和模块的高级使用场景,和在使用它们的过程中常见的陷阱。

爱学习的小码农 825

TypeScript 命名空间与模块

TypeScript 命名空间与模块

一起coding,一起嗨。 827
上一篇: TypeScript 类型保护与区分类型
下一篇: TypeScript JSX
fishmemory7sec
博客等级 码龄5年 1165粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值