Typescript es6导入模块“文件不是模块错误”

我用es6模块语法使用typescript 1.6。

我的文件是:

test.ts:

module App { export class SomeClass { getName(): string { return 'name'; } } } 

main.ts:

 import App from './test'; var a = new App.SomeClass(); 

当我试图编译main.ts文件时,我得到这个错误:

错误TS2306:文件'test.ts'不是一个模块。

我怎么能做到这一点?

扩展 – 根据一些评论提供更多细节

错误

错误TS2306:文件'test.ts'不是一个模块。

来自这里描述的事实http://exploringjs.com/es6/ch_modules.html

17.模块

本章介绍ECMAScript 6中内置模块的工作方式。

17.1概述

在ECMAScript 6中,模块存储在文件中。 每个文件只有一个模块,每个模块只有一个文件。 你有两种从模块中导出东西的方法。 这两种方式可以混合使用,但通常单独使用它们通常会更好。

17.1.1多个命名导出

可以有多个命名导出:

 //------ lib.js ------ export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } ... 

17.1.2单一默认导出

可以有一个默认的导出。 例如,一个函数:

 //------ myFunc.js ------ export default function () { ··· } // no semicolon! 

基于上述我们需要export ,作为test.js文件的一部分。 让我们调整它的内容是这样的:

 // test.js - exporting es6 export module App { export class SomeClass { getName(): string { return 'name'; } } export class OtherClass { getName(): string { return 'name'; } } } 

现在我们可以用以下三种方式导入它:

 import * as app1 from "./test"; import app2 = require("./test"); import {App} from "./test"; 

我们可以像这样消耗import东西:

 var a1: app1.App.SomeClass = new app1.App.SomeClass(); var a2: app1.App.OtherClass = new app1.App.OtherClass(); var b1: app2.App.SomeClass = new app2.App.SomeClass(); var b2: app2.App.OtherClass = new app2.App.OtherClass(); var c1: App.SomeClass = new App.SomeClass(); var c2: App.OtherClass = new App.OtherClass(); 

并调用该方法来看看它的实际运行情况:

 console.log(a1.getName()) console.log(a2.getName()) console.log(b1.getName()) console.log(b2.getName()) console.log(c1.getName()) console.log(c2.getName()) 

原始部分正试图帮助减less命名空间使用的复杂性

原始部分:

我真的强烈build议检查这个问答:

如何在TypeScript外部模块中使用名称空间?

让我引用第一句话:

不要在外部模块中使用“名称空间”。

不要这样做。

认真。 停止。

在这种情况下,我们只是不需要test.ts内部的module 。 这可能是它调整test.ts的内容:

 export class SomeClass { getName(): string { return 'name'; } } 

在这里阅读更多

导出=

在前面的例子中,当我们使用每个validation器时,每个模块只导出一个值。 在这种情况下,使用一个标识符来处理这些符号时,通过它们的限定名称来处理起来会非常麻烦。

export =语法指定从模块中导出的单个对象 。 这可以是类,接口,模块,函数或枚举。 导入时,导出的符号将被直接使用,不受任何名称的限制。

我们以后可以像这样消耗它:

 import App = require('./test'); var sc: App.SomeClass = new App.SomeClass(); sc.getName(); 

在这里阅读更多:

可选模块加载和其他高级加载scheme

在某些情况下,您可能只想在某些条件下加载模块。 在TypeScript中,我们可以使用下面显示的模式来实现这个和其他高级加载场景,以直接调用模块加载器而不会丢失types安全性。

编译器检测每个模块是否在发射的JavaScript中使用。 对于仅用作types系统一部分的模块,不会发出要求调用。 对未使用的引用进行剔除是一个很好的性能优化,并且还允许可选地加载这些模块。

该模式的核心思想是import id = require('…')语句使我们可以访问外部模块公开的types。 模块加载器通过dynamic调用(通过require),如下面的if块所示。 这利用了引用剔除优化,以便只在需要时加载模块。 为了使这个模式起作用,重要的是通过导入定义的符号仅用于types位置(即永远不会放入JavaScript的位置)。

我怎么能做到这一点?

你的例子声明了一个TypeScript <1.5的内部模块 ,现在被称为命名空间 。 旧的module App {}语法现在等同于namespace App {} 。 因此,以下工作:

 // test.ts export namespace App { export class SomeClass { getName(): string { return 'name'; } } } // main.ts import { App } from './test'; var a = new App.SomeClass(); 

话虽如此…

尽量避免导出命名空间 ,而是导出模块(以前称为外部模块 )。 如果需要的话,你可以在导入时使用命名空间,像这样的命名空间导入模式

 // test.ts export class SomeClass { getName(): string { return 'name'; } } // main.ts import * as App from './test'; // namespace import pattern var a = new App.SomeClass();