打字稿:在同一命名空间内跨多个文件的可见性



你能帮我吗 - 这是一个错误还是我误解了文档?

我在命名空间中有两个文件 - 您将在下面找到更简单的版本。

Typescript 文档指出"即使文件是独立的,它们也可以各自贡献到同一个命名空间中,并且可以像它们都在一个中定义一样被使用"。因此,我假设一个文件中的类可以从同一命名空间中访问另一个文件,即使它没有导出。(因为如果它们在同一个地方定义,就会出现这种情况(

但是,tsc抱怨它找不到"调度员"这个名字。为什么会这样?在这一点上,我是否误解了文档?或者它只是一个编译器错误?如果是前者,那就太可惜了,因为只有命名空间的可见性对单元测试和封装有很大帮助。

法典:

(为简单起见,代码已更改。如果存在语法错误,则由以下原因引起(:

应用:

/// <reference path="Dispatcher.ts"/>
namespace Application {
export class Application {
constructor() {
new Dispatcher(); 
}
}
}

调度程序:

namespace Application {
class Dispatcher { /* ... */ }
}

Typescript 文档指出"即使文件是分开的, 它们各自可以贡献到同一个命名空间,并且可以作为 如果它们都在一个定义中"。

这取决于"贡献到同一命名空间"的精确定义。当前的解释是"导出的任何内容在任何地方都可用,未导出的任何内容仅在定义它的命名空间部分中可用"。这是语言规范中的解释:

命名空间提供了一种机制,用于组织代码和声明 命名容器的层次结构。命名空间具有命名成员,这些成员 每个表示一个值、一个类型、一个命名空间或某种组合 其中,这些成员可以是本地的或出口的。身体 命名空间对应于执行一次的函数,从而 提供一种有保证地维持当地状态的机制 隔离。命名空间可以被认为是 立即调用的函数表达式 (IIFE( 模式。

如果同一命名空间有多个声明,则每个声明都会编译到单独的 IIFE 中,如编译的 JavaScript 代码所示Dispatcher.ts

var Application;
(function (Application) {
class Dispatcher {
}
})(Application || (Application = {}));

结果是Dispatcher的作用域在函数内部,并且无法从外部访问。

即使您namespace Application同一个文件中重复两次,每个文件也会定义自己的Dispatcher副本 - 此代码没有错误:

namespace Application {
class Dispatcher { /* ... */ }
}
namespace Application {
class Dispatcher { /* ... */ }
}

使Dispatcher可从外部访问namespace { ... }的唯一方法是将其导出。通过导出,Dispatcher成为Application对象的属性:

namespace Application {
export class Dispatcher { /* ... */ }
}

编译代码:

var Application;
(function (Application) {
class Dispatcher {
}
Application.Dispatcher = Dispatcher;
})(Application || (Application = {}));

此行为在实现方面是有意义的。实现命名空间非常麻烦,以便未导出的对象在所有命名空间实例之间共享,但不能从外部访问。

最新更新