如何在TypeScript中使用同一模块或命名空间中的类?

时间:2016-05-18 09:40:47

标签: typescript

例如,我有以下模块

Foo.Bar.ts

export module Foo {
    export class Bar { }
}

我想在main中使用它,它也属于同一个模块

Main.ts

export module Foo {
    class MainBar {
        constructor() { 
            new Bar(); // doesn't work
        }
    }
}

除非我导入Foo.Bar.ts,否则这不起作用 import * as MyFooBar from "./Foo.Bar";然后以这种方式new MyFooBar.Foo.Bar()使用它。

这似乎有些过分,与示例Java非常不同。告诉我这是唯一的方法吗?

更新
所以我发现post,它仍然没有回答我的问题。并且有点像Roy Dictus建议的那样,但我想这是我现在问题的最接近的答案。

3 个答案:

答案 0 :(得分:1)

你可以写

import {Bar} from "./Foo.Bar";

然后使用

var newBar = new Bar();

答案 1 :(得分:1)

TypeScript模块的工作方式与ES2015 / 2017模块类似。在一天结束时,模块是文件并且它们是异步加载的。

另一方面,模块创建范围,就像手动模块模式实现一样:

Foo = (function() {
    var export = {};
    export.x = 11;
})();

你需要使用import因为函数作用域默认不会导入其他文件(即 modules )变量,函数,...类:应该手动导入

当您需要来自其他模块的内容时,该操作等同于:

// File1.js
Foo = (function(export) {
    export.x = 11;

    return export;
})(Foo || {});


// File2.js
Foo = (function(export) {
    // You access the "x" variable exported from the other file on the Foo module
    export.pow2 = function() {
        return export.x * export.x;
    };

    return export;
})(Foo || {});

在一天结束时,您不能指望Java *.jar或.NET程序集*.dll的行为,因为这些运行时环境在本地计算机上运行应用程序或系统模块在运行时根据本地路径的提示进行链接。例如,当B.dll在某些时候需要A.dll时,因为某些类派生了A.dll中定义的类,运行时会将程序集A.dll加载到内存中。

可悲的是,这种机制在JavaScript上仍然不可用,而且现在将TypeScript转换为该目标语言,因为你的模块只是代码文件,它们不是字节代码或中间语言

也许有WebAssembly的希望!

答案 2 :(得分:0)

在您的代码中,第一个关键字export表示 ES6模块。关键字module应替换为 namespace since TypeScript 1.5。我们可以使用新关键字重写您的代码:

// File Foo.Bar.ts
export namespace Foo {
    export class Bar { }
}

如果目的是组织代码,那么同时使用名称空间模块是不好的做法。您应该在模块和名称空间之间进行选择。

使用ES6模块

TypeScript非常支持ES6模块的语法:

// File Foo.Bar.ts
export default class Bar { }

// File Main.ts
import Bar from './Foo.Bar';
class MainBar {
    constructor() { 
        new Bar();
    }
}

这是推荐的方式。它将适用于Node.js(在编译器选项中使用commonjs模块语法)。或者,在浏览器中,它可以在Webpack(请参阅a tutorial here)或SystemJSa tutorial here)等加载程序的帮助下工作。

有关ES6模块语法的详细介绍,read this article

使用名称空间

如果您不使用模块,请不要import export顶级的任何内容:

// File Foo.Bar.ts
namespace Foo {
    export class Bar { }
}

// File Main.ts
namespace Foo {
    class MainBar {
        constructor() { 
            new Bar();
        }
    }
}

如果您加载两个生成的JavaScript文件,或者如果您将它们连接起来,则此代码将在浏览器上运行,例如uglifyjs