Module typescript中的名称空间和模块混淆?

Module typescript中的名称空间和模块混淆?,module,typescript,namespaces,theory,Module,Typescript,Namespaces,Theory,Typescript的官方网站让我问个问题, “我们是否需要使用命名空间?” 下面的引文很好地解释了这两件事: 需要注意的是,在TypeScript 1.5中,命名法 改变。“内部模块”现在是“名称空间”。“外部模块” 现在只是“模块”,以便与ECMAScript 2015保持一致 术语,(即模块X{等价于 现在首选名称空间X{) 所以,他们建议TS团队更喜欢名称空间。 此外,它说我们应该使用“名称空间”来构造内部模块: 这篇文章概述了使用 TypeScript中的名称空间(以前称为“内部模块”

Typescript的官方网站让我问个问题, “我们是否需要使用命名空间?”

下面的引文很好地解释了这两件事:

需要注意的是,在TypeScript 1.5中,命名法 改变。“内部模块”现在是“名称空间”。“外部模块” 现在只是“模块”,以便与ECMAScript 2015保持一致 术语,(即模块X{等价于 现在首选名称空间X{)

所以,他们建议TS团队更喜欢名称空间。 此外,它说我们应该使用“名称空间”来构造内部模块:

这篇文章概述了使用 TypeScript中的名称空间(以前称为“内部模块”) 在我们关于术语的说明中提到,“内部模块”现在是 称为“名称空间”。此外,模块关键字 在声明内部模块时使用,命名空间关键字可以 并且应该使用。这避免了新用户被 使用类似命名的术语重载它们

上面的引文全部来自名称空间部分,是的,它再次指出,但在内部secnario中。
但在模块部分,有一段说:

从ECMAScript 2015开始,模块是 语言,并应得到所有兼容引擎的支持 因此,对于新项目,模块将是 推荐的代码组织机制

这是否意味着我不需要为名称空间而烦恼,一直使用模块是建议的开发方式

这是否意味着我不需要为名称空间而烦恼,一直使用模块是建议的开发方式

我不会这么说的……这里是对所发生事情的另一种解释。很久以前,打字脚本中使用了两个术语

  • “外部模块”-这是JS社区称之为AMD(如RequireJS)或CommonJS(如NodeJS)模块的TS模拟。这是可选的,对于一些只编写基于浏览器的代码的人来说,他们并不总是为此烦恼,特别是如果他们使用全局文件进行跨文件通信
  • “内部模块”-这是一种组织变量/函数的分层方式,因此并非所有变量都是全局的。JS中也存在同样的模式,即人们将变量组织到对象/嵌套对象中,而不是将它们全部组织到全局
  • 随后出现了Ecmascript 2015(也称ES6),它添加了一种新的正式标准格式,属于“外部模块”类别。由于这一变化,Typescript希望更改术语以匹配新的Javascript标准(因为它喜欢成为Javascript的超集,并尽最大努力避免来自Javascript的用户产生混淆)。因此,“外部模块”的切换被简化为“模块”,而“内部模块”被重命名为“名称空间”

    您在此处找到的报价:

    从ECMAScript 2015开始,模块是语言的本机部分,所有兼容引擎实现都应支持模块。因此,对于新项目,建议使用模块作为代码组织机制

    很有可能是针对那些还没有使用(外部)模块的用户的指南。至少现在考虑使用它。然而,对于ES6模块的支持仍然是不完整的,因为浏览器在2016年5月没有内置的模块加载程序。所以,你必须添加一个PultFube(它在运行时处理它)。比如RequireJS或SystemJS,或者在构建时(在部署到网站之前)处理它的绑定器(比如browserify或webpack)

    那么,您会同时使用模块(以前称为“外部模块”)和名称空间吗?当然-我在代码库中经常使用它们。我使用(外部)模块来组织代码文件

    Typescript中的名称空间非常有用。具体来说,我使用名称空间声明合并作为一种类型安全的方式,向函数对象本身添加额外的属性(JS中经常使用的模式)。此外,虽然名称空间非常类似于常规对象变量,但您可以挂起子类型(嵌套接口、类、枚举等)的名称

    下面是一个具有属性的函数示例(在NodeJS libs中非常常见):

    这允许使用者执行以下常见的NodeJS模式:

    // asynchronous consumer
    someUsefulFunction()
      .then(() => {
        // ... 
      });
    
    // synchronous consumer
    someUsefulFunction.sync();
    
    类似地,假设您有一个接收选项对象的API。如果该选项类型特定于该API

    function myFunc(options?: myFunc.Options) {
        // ...
    }
    
    namespace myFunc {
        export interface Options {
            opt1?: number;
            opt2?: boolean;
            opt3?: string;
        }
    }
    
    在这种情况下,您不必使用选项的类型声明来污染更大的名称空间(比如整个模块范围)


    希望这有帮助!

    是的,我就是这么理解的。使用ES风格的模块,而不是TS名称空间。这取决于您想做什么。如果您想使用模块系统(requirejs等)然后,您需要使用模块。如果您正在使用正则脚本元素加载所有js,并且希望它们都共享结构,那么请使用名称空间。如果您正在使用模块,并且希望构建模块,那么请在模块内使用名称空间。
    function myFunc(options?: myFunc.Options) {
        // ...
    }
    
    namespace myFunc {
        export interface Options {
            opt1?: number;
            opt2?: boolean;
            opt3?: string;
        }
    }