我开始研究大型打字稿项目。
从一开始,我就想保持我的文件有条理(这个项目将在很多开发人员之间分开,所以订单非常必要)。
我一直在尝试使用模块/命名空间并将类拆分为每个文件的单独文件,其中包含一个包含命名空间的文件夹。
文件结构为:
app.ts
\Classes
---- \Animals
---- ---- Mammals.ts
---- ---- Reptiles.ts
然后尝试使用以下内容导入app.ts中该命名空间中的所有文件:import * as Animals from "./Classes/Animals"
至于命名空间文件本身,我尝试了以下操作,但没有成功:
namespace Animals {
export class Mammals {
constructor() {
}
}
}
还有:
module Animals {
export class Reptiles {
constructor() {
}
}
}
不幸的是,路径永远不会被识别(因为它指向文件夹而不是单个文件)。这甚至可能吗?将一个名称空间中的所有类放在一个文件中将导致文件长达数千行,并且该项目不可维护。
我还注意到TypeScript 1.5支持tsconfig.json - 但是,必须手动将每个文件添加到地图中,这是在开发人员开始添加类时引入问题的可靠方法。
注意:我使用的是Visual Studio 2015,TypeScript 1.5(我相信,不知道如何验证)。我也开启了ES6支持。
答案 0 :(得分:23)
使用重新导出来创建一个外部模块,用于对来自其他模块的类型进行分组和公开:
// Classes/Animals.ts
export * from '.\Animals\Mammals';
export * from '.\Animals\Reptiles';
然后照常从新模块导入类型:
// app.ts
import * as Animals from '.\Classes\Animals'
let dog: Animals.Dog;
let snake: Animals.Snake;
或者
// app.ts
import { Dog, Snake } from '.\Classes\Animals'
let dog: Dog;
let snake: Snake;
答案 1 :(得分:13)
找到了实现目标的方法,但没有找到命名空间关键字。
答案 2 :(得分:1)
外部模块意味着您逐个文件加载模块。 AMD和CommonJS都没有命名空间这样的东西。您可以使用某种后处理方法将文件捆绑在一个模块中。
以下定义了一个内部模块:
module Animals {
export class Reptiles {
constructor() {
}
}
}
您不应该使用import
。任何地方都可以看到Animals.Reptiles
。唯一的目标是以正确的顺序加载脚本(例如在heritors之前的基类)。因此,您应列出ts.config
或其他地方的所有文件。在我的项目中,我在文件夹上使用bundle,并且有一个约定将@
添加到基类的文件名中。
另一个解决方案是使用外部模块:AMD(RequireJS)或CommonJS(Browserify)。在这种情况下,从声明中删除上级module
。如果一个文件只包含一种类型,则可以将其作为根目录导出:
class Reptiles {
constructor() {
}
}
export = Reptiles;
您可以按文件路径引用模块:
import Reptilies = require('..\Animals\Reptilies')
var reptile = new Reptile();
或者使用新的ES6模块:
export class Reptiles {
constructor() {
}
}
import { Reptiles } from '..\Animals\Reptilies';
答案 3 :(得分:1)
如果您拥有自己的库,并且想要从名称空间中导出多个文件,则可以执行以下操作:
// index.ts
import * as Animals from './animals';
export { Animals };
答案 4 :(得分:0)
似乎没有办法单独使用名称空间(除非您要使用Module Augmentation和declare
每个要单独添加的新项目);但是,名称空间可以是类的一部分,可以扩展!这是我能找到的最佳选择:
CoreLibraryTypes.ts
abstract class Types { }
namespace Types {
export class TypeA { }
export class TypeB { }
export class TypeC { }
}
export { Types };
CoreTypesExtended.ts
import CoreLibraryTypes from "./CoreLibraryTypes";
abstract class Types extends CoreLibraryTypes { }
namespace Types {
export class TypeD { }
export class TypeE { }
export class TypeF { }
}
export { Types };
当然,缺点是只有第二个模块的导入会添加新的类型。第一个模块将保持不变。理想情况下,最好用其他类型(例如来自插件)“更新”类型的名称空间,这样可以更自然地支持模块增强(而不是必须手动编写),但是我想这必须要做到有人通过手动声明更新的定义来实现模块的扩展,这只是做名称空间已经做的事情的半价方式(包括上面看到的类,可以使用名称空间合并作为类的一部分)。 ;)
注意:在上面的示例中,我使用export { Types };
是有原因的-这将允许其他人扩充我的模块。默认导出不支持增强(除非需要,除非将其密封)。