在 TypeScript 中如何将多个外部模块放入同一个命名空间?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12882748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:15:35  来源:igfitidea点击:

How do you put multiple external modules into the same namespace in TypeScript?

typescript

提问by Brent

Say I want to have one class per .ts file. I have two .ts files, that look like so:

假设我希望每个 .ts 文件有一个类。我有两个 .ts 文件,看起来像这样:

export module MyClasses { export class A {} }

and

export module MyClasses { export class B {} }

I can't do this:

我不能这样做:

import MyClasses = module('A');
import MyClasses = module('B');

How do I define classes in separate files and put them into the same "namespace"? Furthermore, we end up having to do something like:

如何在单独的文件中定义类并将它们放入相同的“命名空间”?此外,我们最终不得不做这样的事情:

MyClasses.MyClasses.A

instead of

代替

MyClasses.A

What's the point of this additional level of hierarchy? So that you can have more than one exported module in a module file? The best solution I've figure out so far is to remove "export module" (since "export class" seems to be sufficient when compiling AMD), which moves the class up one hierarchical level. Then:

这个额外的层次结构有什么意义?这样您就可以在一个模块文件中拥有多个导出的模块?到目前为止,我想出的最佳解决方案是删除“导出模块”(因为在编译 AMD 时“导出类”似乎就足够了),这将类向上移动了一个层次级别。然后:

import AModule = module('A');
module MyClasses{ var A = AModule.A; }
import BModule = module('B');
module MyClasses { var B = BModule.B; }

Though it works perfectly, it's not exactly succinct. Is there not a better way to do this?

虽然它工作得很好,但它并不完全简洁。没有更好的方法来做到这一点吗?

回答by Wolfgang

Unfortunately there does not seem to be a perfect solution but this is how I solved it for now:

不幸的是,似乎没有完美的解决方案,但这就是我现在解决的方法:

File 'Controllers/MainController.ts':

文件“控制器/MainController.ts”:

class MainController {
    ...
}

export = MainController;

File 'Controllers/SecondController.ts':

文件“控制器/SecondController.ts”:

class SecondController {
    ...
}

export = SecondController;

File 'Controllers/Namespace.ts':

文件“控制器/命名空间.ts”:

import MainController = require('./MainController');
import SecondController = require('./SecondController');

export = { MainController, SecondController }

File 'App.ts' (where the 'namespace' is used)

文件“App.ts”(使用“命名空间”的地方)

import Controllers = require('Controllers/Namespace');

angular.module('app', [])
    .controller('MainController', Controllers.MainController)
    .controller('SecondController', Controllers.SecondController)

This gives you nice intellisense, hides the 400 import statements away and keeps the code where the namespace is actually used pretty clean...

这为您提供了很好的智能感知,隐藏了 400 条导入语句,并使实际使用名称空间的代码非常干净......

回答by Valentin

I don't think there is a better way to achieve this with externalmodules. The language specification defines external modules as follows:

我认为使用外部模块没有更好的方法来实现这一点。语言规范定义外部模块如下:

External modules (section 9.4) are separately loaded bodies of code referenced using external module names. An external module is written as a separate source file that contains at least one import or export declaration.

外部模块(第 9.4 节)是使用外部模块名称引用的单独加载的代码体。外部模块被编写为包含至少一个导入或导出声明的单独源文件。

Further down it says that internalmodules are open ended and can extend over multiple files:

再往下说,内部模块是开放式的,可以扩展到多个文件:

Internal modules are “open-ended” and internal module declarations with the same qualified name relative to a common root (as defined in section 2.2) contribute to a single module.

内部模块是“开放式”的,并且相对于公共根(如第 2.2 节中定义的)具有相同限定名称的内部模块声明有助于单个模块。

I found no other mentioning of a similar statement for external modules. I'm pretty much convinced it's not. If you need module loading, then you'll have to live with reference paths to access types loaded from different files.

我发现没有其他提及外部模块的类似声明。我非常确信它不是。如果您需要加载模块,那么您将不得不使用引用路径来访问从不同文件加载的类型。

However, for me it sounds like you'd better go for internal modules. Then you can simply spread your module over two files

但是,对我来说,听起来您最好选择内部模块。然后你可以简单地将你的模块分布在两个文件中

export module MyClasses { export class A {} }

and

export module MyClasses { export class B {} }

bring them into scope with reference paths

使用参考路径将它们带入范围

///<reference path='A.ts'/>
///<reference path='B.ts'/>

and then simply reference them with the module name such as e.g.

然后简单地使用模块名称引用它们,例如

var a = new MyClasses.A();

回答by Fenton

Excuse the poor variable names, I was testing this in Visual Studio. It worked for my when using different names for the import statements.

原谅我的变量名不好,我在 Visual Studio 中测试了这个。当为导入语句使用不同的名称时,它对我有用。

import x = module('A');
import y = module('B');

x.MyClasses.A;
y.MyClasses.B;

Alternatively, you can use reference comments to a similar effect, but this is better if you are bundling, not if you are using module loading. You would need to drop the exportkeyword from your two MyClassesdeclarations:

或者,您可以使用引用注释来达到类似的效果,但如果您是捆绑的,这会更好,而不是使用模块加载。您需要export从两个MyClasses声明中删除关键字:

///<reference path='A.ts'/>
///<reference path='B.ts'/>

var x = MyClasses.A;