我有一些代码:

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。生物。植物。树。它不能跨文件在同一个名称空间中组合多个对象。我怎么做呢?


当前回答

白化病小改善答案:

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);

其他回答

组织代码的正确方法是使用单独的目录来代替名称空间。每个类都在它自己的文件中,在它各自的命名空间文件夹中。索引。Ts只会重新导出每个文件;索引中不应包含实际代码。ts文件。以这样的方式组织您的代码使得导航更加容易,并且是基于目录结构的自文档化。

// index.ts
import * as greeter from './greeter';
import * as somethingElse from './somethingElse';

export {greeter, somethingElse};

// greeter/index.ts
export * from './greetings.js';
...

// greeter/greetings.ts
export const helloWorld = "Hello World";

然后你可以这样使用它:

import { greeter } from 'your-package'; //Import it like normal, be it from an NPM module or from a directory.
// You can also use the following syntax, if you prefer:
import * as package from 'your-package';

console.log(greeter.helloWorld);

你可以使用*作为wrapper_var语法,使所有导入的方法都可以在wrapper_var下访问:

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

伙计,我支持你。 同样,在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 {} .

包装它们,这样它们就不会试图访问具有相同名称的其他类,当它们只是简单地试图从它们上面的类获得引用时。

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 {
    }
}

关于这个主题,我看到的一些问题/评论听起来好像这个人在使用Namespace,他们的意思是“模块别名”。正如Ryan Cavanaugh在他的评论中提到的,你可以有一个'Wrapper'模块重新导出几个模块。

如果您真的想从相同的模块名/别名导入它,可以将包装器模块与tsconfig.json中的路径映射结合起来。

例子:

- path / to / CompanyName t.s.产品- Foo。

export class Foo {
    ...
}

- path / to / CompanyName。产品- t.s.酒吧。

export class Bar {
    ...
}

- path / to / CompanyName。产品/ index . ts

export { Foo } from './Foo';
export { Bar } from './Bar';

tsconfig.json

{
    "compilerOptions": {
        ...
        paths: {
            ...
            "CompanyName.Products": ["./path/to/CompanyName.Products/index"],
            ...
        }
        ...
    }
    ...
}

main.ts

import { Foo, Bar } from 'CompanyName.Products'

注意:输出.js文件中的模块解析需要以某种方式处理,例如使用这个https://github.com/tleunen/babel-plugin-module-resolver

示例:.babelrc处理别名解析:

{
    "plugins": [
        [ "module-resolver", {
            "cwd": "babelrc",
            "alias": {
                "CompanyName.Products": "./path/to/typescript/build/output/CompanyName.Products/index.js"
            }
        }],
        ... other plugins ...
    ]
}