在 TypeScript 中使用分布在多个模块文件上的命名空间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31983209/
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
Using namespace spread over multiple module files in TypeScript
提问by aaron-bond
I've started work on a large-scale typescript project.
我已经开始从事一个大型打字稿项目。
Right from the outset, I want to keep my files organized (this project will be split between lots of developers so order is very necessary).
从一开始,我就想让我的文件井井有条(这个项目将在许多开发人员之间分配,因此顺序非常必要)。
I have been attempting to use modules / namespaces and splitting classes out into separate files for each one, with a folder holding the namespace.
我一直在尝试使用模块/命名空间并将类拆分为每个单独的文件,并使用一个文件夹保存命名空间。
The file structure is:
文件结构为:
app.ts
\Classes
---- \Animals
---- ---- Mammals.ts
---- ---- Reptiles.ts
I then attempt to import all files in that namespace in app.ts using something like: import * as Animals from "./Classes/Animals"
然后我尝试使用以下内容导入 app.ts 中该命名空间中的所有文件: import * as Animals from "./Classes/Animals"
As for the namespace files themselves, I have tried the following, with no success:
至于命名空间文件本身,我尝试了以下方法,但没有成功:
namespace Animals {
export class Mammals {
constructor() {
}
}
}
and also:
并且:
module Animals {
export class Reptiles {
constructor() {
}
}
}
Unfortunately, the path is never recognized (as it points to a folder and not a single file). Is this even possible? Having all my classes from a single namespace in one file will result in files which are thousands of lines long and for this project that is not maintainable.
不幸的是,路径永远不会被识别(因为它指向一个文件夹而不是单个文件)。这甚至可能吗?将我的所有类都来自一个文件中的单个命名空间将导致文件长达数千行,并且对于这个项目来说是不可维护的。
I have also noticed that TypeScript 1.5 has support for tsconfig.json- however, having to add each file manually to the map is a sure-fire way of introducing issues when developers start adding classes.
我还注意到 TypeScript 1.5 支持tsconfig.json- 但是,当开发人员开始添加类时,必须手动将每个文件添加到映射中肯定会引入问题。
NOTE: I'm using Visual Studio 2015, TypeScript 1.5 (I believe, not sure how to verify). I also have ES6 support turned on.
注意:我使用的是 Visual Studio 2015,TypeScript 1.5(我相信,不确定如何验证)。我也开启了 ES6 支持。
采纳答案by Vadim Macagon
Use re-exporting to create an external module that groups and exposes types from other modules:
使用重新导出创建一个外部模块,该模块对其他模块的类型进行分组和公开:
// Classes/Animals.ts
export * from '.\Animals\Mammals';
export * from '.\Animals\Reptiles';
Then import the types from the new module as usual:
然后像往常一样从新模块导入类型:
// app.ts
import * as Animals from '.\Classes\Animals'
let dog: Animals.Dog;
let snake: Animals.Snake;
Or
或者
// app.ts
import { Dog, Snake } from '.\Classes\Animals'
let dog: Dog;
let snake: Snake;
回答by Val
Found a way to achieve your goal but not with the namespace keyword.
找到了一种方法来实现您的目标,但不是使用 namespace 关键字。
- The "Animals" classes, Animal.ts & Mammal.ts & Reptile.ts under namespace.
- with index.ts for the barrel.
- animals.ts for namespace grouping.
- 命名空间下的“动物”类,Animal.ts & Mammal.ts & Reptile.ts。
- 桶的 index.ts。
- 命名空间分组的animals.ts。
Sample Classes:
示例类:
index.ts (as barrel)
index.ts(作为桶)
animals.ts (for namespace grouping)
Animal.ts(用于命名空间分组)
And here you go of the concept of the namespace.
这就是命名空间的概念。
回答by James Wilkins
Seems there is no way to do this using namespaces on their own (unless you want to use Module Augmentationand declare
every new item to add separately); however, a namespace can be part of a class, which can be extended! This is the best alternative I can find:
似乎没有办法单独使用命名空间来做到这一点(除非你想使用模块扩充和declare
每个新项目单独添加);但是,命名空间可以是类的一部分,可以扩展!这是我能找到的最佳选择:
CoreLibraryTypes.ts
CoreLibraryTypes.ts
abstract class Types { }
namespace Types {
export class TypeA { }
export class TypeB { }
export class TypeC { }
}
export { Types };
CoreTypesExtended.ts
CoreTypesExtended.ts
import CoreLibraryTypes from "./CoreLibraryTypes";
abstract class Types extends CoreLibraryTypes { }
namespace Types {
export class TypeD { }
export class TypeE { }
export class TypeF { }
}
export { Types };
The downside, of course, is that only the import of the second module will have the new types added. The first module will remain as before. Ideally it would be nice to "update" a namespace of types with additional types (like from plugins), such that module augmentation was more naturally supported (instead of having to write it by hand), but I guess that will have to do until someone realizes augmentation of modules by manually declaring updated definitions is just a half-a$$ way to do what namespaces already do lol (including classes, as seen above, which can already use namespace merging as part of the class). ;)
当然,缺点是只有第二个模块的导入才会添加新类型。第一个模块将保持原样。理想情况下,使用附加类型(例如来自插件)“更新”类型的命名空间会很好,这样模块扩充就得到更自然的支持(而不是必须手动编写),但我想这将不得不这样做,直到有人通过手动声明更新的定义来实现模块的扩充只是做命名空间已经做的事情的一种半美元的方式,哈哈(包括类,如上所示,它已经可以使用命名空间合并作为类的一部分)。;)
Note: In the example above I used export { Types };
for a reason - this will allow others to augment my modules. Augmentation is not supported for default exports (unless that is desired - sort of seals it virtually).
注意:在上面的示例中,我export { Types };
出于某种原因使用 - 这将允许其他人扩充我的模块。默认导出不支持增强(除非需要 - 虚拟地密封它)。
回答by ktretyak
If you have your own library and you want to export the multiple files like from namespace, you can do this:
如果您有自己的库并且想要从命名空间导出多个文件,您可以这样做:
// index.ts
import * as Animals from './animals';
export { Animals };
回答by Artem
External modules imply that you load modules file by file. Both AMD and CommonJS do not have such thing as namespace. You can use some kind of postprocessing to bundle files in one module.
外部模块意味着您逐个文件加载模块。AMD 和 CommonJS 都没有命名空间之类的东西。您可以使用某种后处理将文件捆绑在一个模块中。
The following defines an internal module:
下面定义了一个内部模块:
module Animals {
export class Reptiles {
constructor() {
}
}
}
You shouldn't use import
for it. Animals.Reptiles
is visible anywhere. The only aim is to load scripts in the proper order (e.g. base classes before heritors). So you should list all files in ts.config
or somewhere else. In my project I use bundles on folders and have a convention to add @
to filenames of base classes.
你不应该使用import
它。Animals.Reptiles
随处可见。唯一的目的是以正确的顺序加载脚本(例如继承者之前的基类)。因此,您应该列出其中ts.config
或其他地方的所有文件。在我的项目中,我在文件夹上使用包,并有一个约定来添加@
到基类的文件名。
Another solution is to use external modules: AMD (RequireJS) or CommonJS (Browserify). In that case remove upper level module
from declaration. If one file contains only one type you can export it as a root:
另一种解决方案是使用外部模块:AMD ( RequireJS) 或 CommonJS ( Browserify)。在这种情况下,module
从声明中删除上层。如果一个文件只包含一种类型,您可以将其导出为根:
class Reptiles {
constructor() {
}
}
export = Reptiles;
You can refer module by file path:
您可以通过文件路径引用模块:
import Reptilies = require('..\Animals\Reptilies')
var reptile = new Reptile();
Or with new ES6 modules:
或者使用新的 ES6 模块:
export class Reptiles {
constructor() {
}
}
import { Reptiles } from '..\Animals\Reptilies';