打字稿中的命名空间和模块混淆?

Namespace and module confusion in typescript?

打字稿的官方网站让我问一个问题, "Do we need to use namespace or not?".

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

It’s important to note that in TypeScript 1.5, the nomenclature has changed. “Internal modules” are now “namespaces”. “External modules” are now simply “modules”, as to align with ECMAScript 2015’s terminology, (namely that module X { is equivalent to the now-preferred namespace X {).

因此,他们建议 TS 团队更喜欢命名空间。 此外,它说我们应该使用 "namespace" 来构造内部模块:

This post outlines the various ways to organize your code using namespaces (previously “internal modules”) in TypeScript. As we alluded in our note about terminology, “internal modules” are now referred to as “namespaces”. Additionally, anywhere the module keyword was used when declaring an internal module, the namespace keyword can and should be used instead. This avoids confusing new users by overloading them with similarly named terms.

上面的引用全部来自命名空间部分,是的,它又说了一遍,但是是在一个内部场景中。
但是在模块部分,有一段说:

Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism.

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

Does it mean that I don't need to bother with namespace, use module all along is the suggested way to develop?

我不会完全那样说...这是对发生的事情的另一种解释。曾几何时,Typescript

中使用了两个术语
  1. "external modules" - 这是 TS 模拟 JS 社区所称的 AMD(例如 RequireJS)或 CommonJS(例如 NodeJS)模块。这是可选的,对于一些只编写基于浏览器的代码的人来说,他们并不总是为此烦恼,尤其是当他们使用全局变量跨文件通信时。
  2. "internal modules" - 这是组织 variables/functions 的分层方式,因此并非所有内容都是全局的。 JS 中存在相同的模式,人们将变量组织到 objects/nested 对象中,而不是将它们全部设为全局。

随之而来的是 Ecmascript 2015 (a.k.a.ES6),它添加了属于 "external modules" 类别的新的正式标准格式。由于此更改,Typescript 想要更改术语以匹配新的 Javascript 标准(因为它喜欢成为 Javascript 的超集,并尽力避免来自 Javascript).因此,"external modules" 的开关被简化为 "modules","internal modules" 被重命名为 "namespaces"。

您在此处找到的引用:

Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism.

可能暗指对尚未使用(外部)模块的用户的指导。至少现在考虑使用它。然而,对 ES6 模块的支持仍然不完整,因为截至 2016 年 5 月的浏览器没有内置模块加载器。因此,您要么必须添加一个 polyfill(在运行时处理它),如 RequireJS 或 SystemJS,要么添加一个在构建时(在部署到您的网站之前)处理它的捆绑器(如 browserify 或 webpack)。

那么,您会同时使用模块(以前的 "external modules")和命名空间吗?绝对 - 我在我的代码库中经常使用它们。我使用(外部)模块来组织我的代码文件。

Typescript 中的

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

这是一个带有 属性 的函数示例(在 NodeJS 库中很常见):

function someUsefulFunction() {
  // asynchronous version
  return ...; // some promise
}

namespace someUsefulFunction {
  export function sync() {
    // synchronous version
  }
}

这允许消费者执行这种常见的 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;
    }
}

在那种情况下,您不必使用选项的类型声明来污染更大的名称空间(比如整个模块范围)。

希望对您有所帮助!