我有一些代码:
baseTypes.ts
export namespace Living.Things {
export class Animal {
move() { /* ... */ }
}
export class Plant {
photosynthesize() { /* ... */ }
}
}
dog.ts
import b = require('./baseTypes');
export namespace Living.Things {
// Error, can't find name 'Animal', ??
export class Dog extends Animal {
woof() { }
}
}
tree.ts
// Error, can't use the same name twice, ??
import b = require('./baseTypes');
import b = require('./dogs');
namespace Living.Things {
// Why do I have to write b.Living.Things.Plant instead of b.Plant??
class Tree extends b.Living.Things.Plant {
}
}
这让人很困惑。我想有一堆外部模块,它们都向同一个命名空间Living.Things贡献类型。这似乎根本不管用——我在dogs.ts中看不到Animal。我必须写出完整的命名空间名字b。生物。植物。树。它不能跨文件在同一个名称空间中组合多个对象。我怎么做呢?
伙计,我支持你。
同样,在300多票的情况下,这个答案没有错,但我的观点是:
what is wrong with putting classes into their cozy warm own files individually?
I mean this will make things looks much better right? (or someone just like a 1000 line file for all the models)
so then, if the first one will be achieved, we have to import import import... import just in each of the model files like man, srsly, a model file, a .d.ts file, why there are so many *s in there? it should just be simple, tidy, and that's it. Why I need imports there? why? C# got namespaces for a reason.
And by then, you are literally using "filenames.ts" as identifiers. As identifiers... Come on its 2017 now and we still do that? Ima go back to Mars and sleep for another 1000 years.
因此,遗憾的是,我的回答是:不,如果不使用所有这些导入或使用这些文件名作为标识符(我认为这真的很愚蠢),您就不能使“名称空间”东西起作用。另一种选择是:将所有这些依赖项放入一个名为filenameasidentifier的框中。t和用法
export namespace(or module) boxInBox {} .
包装它们,这样它们就不会试图访问具有相同名称的其他类,当它们只是简单地试图从它们上面的类获得引用时。
尝试按文件夹组织:
baseTypes.ts
export class Animal {
move() { /* ... */ }
}
export class Plant {
photosynthesize() { /* ... */ }
}
dog.ts
import b = require('./baseTypes');
export class Dog extends b.Animal {
woof() { }
}
tree.ts
import b = require('./baseTypes');
class Tree extends b.Plant {
}
LivingThings.ts
import dog = require('./dog')
import tree = require('./tree')
export = {
dog: dog,
tree: tree
}
main.ts
import LivingThings = require('./LivingThings');
console.log(LivingThings.Tree)
console.log(LivingThings.Dog)
这个想法是你的模块本身不应该关心/知道它们正在参与一个命名空间,但是这以一种紧凑、合理的方式将你的API暴露给消费者,而不知道你正在为项目使用哪种类型的模块系统。
白化病小改善答案:
base.ts
export class Animal {
move() { /* ... */ }
}
export class Plant {
photosynthesize() { /* ... */ }
}
dog.ts
import * as b from './base';
export class Dog extends b.Animal {
woof() { }
}
things.ts
import { Dog } from './dog'
namespace things {
export const dog = Dog;
}
export = things;
main.ts
import * as things from './things';
console.log(things.dog);
伙计,我支持你。
同样,在300多票的情况下,这个答案没有错,但我的观点是:
what is wrong with putting classes into their cozy warm own files individually?
I mean this will make things looks much better right? (or someone just like a 1000 line file for all the models)
so then, if the first one will be achieved, we have to import import import... import just in each of the model files like man, srsly, a model file, a .d.ts file, why there are so many *s in there? it should just be simple, tidy, and that's it. Why I need imports there? why? C# got namespaces for a reason.
And by then, you are literally using "filenames.ts" as identifiers. As identifiers... Come on its 2017 now and we still do that? Ima go back to Mars and sleep for another 1000 years.
因此,遗憾的是,我的回答是:不,如果不使用所有这些导入或使用这些文件名作为标识符(我认为这真的很愚蠢),您就不能使“名称空间”东西起作用。另一种选择是:将所有这些依赖项放入一个名为filenameasidentifier的框中。t和用法
export namespace(or module) boxInBox {} .
包装它们,这样它们就不会试图访问具有相同名称的其他类,当它们只是简单地试图从它们上面的类获得引用时。
Ryan的回答没有错,但是对于那些来这里寻找如何在正确使用ES6名称空间的情况下维护一个类一个文件结构的人,请参考来自微软的有用资源。
在阅读文档后,我不清楚的一件事是:如何用一个导入导入整个(合并的)模块。
编辑
转回来更新这个答案。TS中出现了几种命名空间的方法。
所有模块类都在一个文件中。
export namespace Shapes {
export class Triangle {}
export class Square {}
}
将文件导入命名空间,并重新分配
import { Triangle as _Triangle } from './triangle';
import { Square as _Square } from './square';
export namespace Shapes {
export const Triangle = _Triangle;
export const Square = _Square;
}
桶
// ./shapes/index.ts
export { Triangle } from './triangle';
export { Square } from './square';
// in importing file:
import * as Shapes from './shapes/index.ts';
// by node module convention, you can ignore '/index.ts':
import * as Shapes from './shapes';
let myTriangle = new Shapes.Triangle();
最后一点考虑。您可以为每个文件命名空间
// triangle.ts
export namespace Shapes {
export class Triangle {}
}
// square.ts
export namespace Shapes {
export class Square {}
}
但是当一个从同一个名称空间导入两个类时,TS会抱怨标识符重复。此时唯一的解决方案是别名命名空间。
import { Shapes } from './square';
import { Shapes as _Shapes } from './triangle';
// ugh
let myTriangle = new _Shapes.Shapes.Triangle();
这种混叠是绝对可恶的,所以不要这样做。你最好采用上面的方法。就我个人而言,我更喜欢“桶”。
dog.ts
import b = require('./baseTypes');
export module Living.Things {
// Error, can't find name 'Animal', ??
// Solved: can find, if properly referenced; exporting modules is useless, anyhow
export class Dog extends b.Living.Things.Animal {
public woof(): void {
return;
}
}
}
tree.ts
// Error, can't use the same name twice, ??
// Solved: cannot declare let or const variable twice in same scope either: just use a different name
import b = require('./baseTypes');
import d = require('./dog');
module Living.Things {
// Why do I have to write b.Living.Things.Plant instead of b.Plant??
class Tree extends b.Living.Things.Plant {
}
}