我已经阅读了(再次)使用Typescript的文档来清除模块和命名空间的内容,但我仍然有一些暗点。
declare namespace Foo{}
namespace Foo{}
export namespace Foo{}
在这3种创建命名空间的方法中,每种方法的用途是什么?
假设我想创建一个 Validation 命名空间,我有3个文件可以为该命名空间做出贡献。这样做的正确方法是什么,以及如何从另一个文件/模块导入(使用)Validation命名空间中的代码?
答案 0 :(得分:2)
这样做的正确方法是什么以及我将如何进行 从另一个文件/模块导入(使用)Validation命名空间中的代码?
当您在一个问题中说“导入(使用)”和“文件/模块”时,您会询问两种截然不同的情况,每种情况的答案都不同。
使用import
和模块无法做到这一点。每个模块都是一个独立的,独立的范围,如果在每个模块中定义namespace Validation
,您将创建3个不同的命名空间,因为不合并来自不同范围的声明。好吧,你可以使用declare global
打破模块范围,但它违背了模块的既定目的 -
消除全局变量。
您可以使用非模块的文件(即没有任何顶级import
或export
的文件)来执行此操作。但是,你只能使用非模块化的javascript(或打字稿)。您的namespace Validation
将在全局范围内,您不能使用import
和模块,并且您必须编译并连接所有文件,生成适合使用<script>
加载的单个脚本标签
另见How do I use namespaces with TypeScript external modules?
至于具体的语法变体
declare namespace Foo {}
这声明存在名称空间Foo,在某个外部文件中定义(未包含在当前编译中),允许使用Foo
,假定它包含在{}
中声明的内容(和{{ 1}}可能只包含声明,而不包含定义)
{}
这会创建名称空间namespace Foo {}
Foo
这也会创建名称空间Foo,但export namespace Foo {}
可能有不同的含义,具体取决于它在源文件中的位置(它还取决于文件是否是模块,但我不想详细了解export
如何在没有模块的情况下有用)。
如果export
位于顶层,则会将文件转换为模块,并使export
可用于导入和使用(但不扩展)其他模块。如果Foo
不在顶层,那么它又取决于:如果它在某个导出的命名空间中,它定义嵌套的命名空间,可由导入该外部命名空间的模块访问。如果它在非导出的命名空间中,export
没有效果,我相信。