我有一些代码:
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。生物。植物。树。它不能跨文件在同一个名称空间中组合多个对象。我怎么做呢?
尝试按文件夹组织:
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暴露给消费者,而不知道你正在为项目使用哪种类型的模块系统。
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();
这种混叠是绝对可恶的,所以不要这样做。你最好采用上面的方法。就我个人而言,我更喜欢“桶”。
尝试按文件夹组织:
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暴露给消费者,而不知道你正在为项目使用哪种类型的模块系统。
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 {
}
}
白化病小改善答案:
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);