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