我使用带有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:文件测试。
我怎么才能做到呢?
扩展 -基于一些注释提供更多细节
误差错误TS2306:文件测试。t '不是一个模块。
来自于这里描述的事实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";
我们可以像这样消费进口的东西:
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())
原始部分试图帮助减少使用命名空间
的复杂性原始的部分:我强烈建议你看看这个Q &答:
我如何使用命名空间与TypeScript外部模块?
让我引用第一句话:
不要使用"名称空间"。在外部模块中。
不要这样做。
认真。停止。
…
在这种情况下,我们只是不需要 module
在test.ts
。这可以是它调整后的内容 test.ts
:
export class SomeClass
{
getName(): string
{
return 'name';
}
}
点击这里阅读更多
出口=在前面的例子中,当我们使用每个验证器时,每个模块只导出一个值。在这种情况下,当使用单个标识符就可以完成相同的工作时,通过限定名处理这些符号是很麻烦的。
export =
语法指定从模块导出的单个对象。它可以是类、接口、模块、函数或枚举。当导入时,导出的符号被直接使用,并且不受任何名称的限制。
我们以后可以这样使用它:
import App = require('./test');
var sc: App.SomeClass = new App.SomeClass();
sc.getName();
阅读更多:
可选模块加载和其他高级加载场景
在某些情况下,您可能只希望在某些条件下加载模块。在TypeScript中,我们可以使用下面的模式来实现这个和其他高级加载场景,直接调用模块加载器,而不会失去类型安全。
编译器检测每个模块是否在发出的JavaScript中被使用。对于仅作为类型系统一部分使用的模块,不会发出require调用。这种对未使用的引用的剔除是一种很好的性能优化,并且还允许可选加载这些模块。
该模式的核心思想是import id = require('…')语句允许我们访问外部模块公开的类型。模块加载器是动态调用的(通过require),如下面的if块所示。这利用了引用剔除优化,以便只在需要时加载模块。要使此模式工作,通过import定义的符号仅用于类型位置(即永远不要用于会被发送到JavaScript中的位置)是很重要的。
以上答案正确。但是以防万一……在VS Code中得到相同的错误。必须重新保存/重新编译抛出错误的文件。
我该怎么做呢?
你的例子声明了一个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();
除了A. Tim的答案之外,有时即使这样也不起作用,所以你需要:
- 使用智能感知重写导入字符串。有时这会修复问题
- 重启VS代码
我有这个问题,我忘记导出类。
万一这对你有用,就像它对我一样,我有这些文件
//server.ts
class Server{
...
}
exports.Server = Server
//app.ts
import {Server} from './server.ts'
这实际上引发了一个错误但是我将server.ts
更改为
//server.ts
export class Server{
...
}
并且成功了😎👌
注意:我正在使用这个配置
"target": "esnext",
"module": "commonjs",
我在一个没有导出的模块中遇到了同样的问题。我用它只是为了治疗副作用。这是TypeScript文档中关于导入副作用模块的说明:
虽然不推荐这样做,但有些模块会设置一些全局状态,供其他模块使用。这些模块可能没有任何导出,或者使用者对它们的任何导出都不感兴趣。要导入这些模块,使用:
import "./my-module.js";
在这种情况下,你可以修复"文件不是一个模块"导出空对象错误:
// side-effects stuff
export default {};
除了Tim的回答之外,当我拆分重构一个文件,将其拆分为自己的文件时,这个问题也发生在我身上。
VSCode,由于某种原因,缩进了我的[class]代码的部分,这导致了这个问题。一开始很难注意到这一点,但当我意识到代码缩进后,我格式化了代码,问题就消失了。
例如,在粘贴过程中,Class定义第一行之后的所有内容都会自动缩进。export class MyClass extends Something<string> {
public blah: string = null;
constructor() { ... }
}
我在vue组件
中面临同样的问题("File is not a module error")import handleClientLoad from "../../../public/js/calendar.js"
我这样做并解决它
// @ts-ignore
import handleClientLoad from "../../../public/js/calendar.js"
空文件
虽然不是在您的情况下,但对于其他观众,我在创建新的.ts
文件后遇到了同样的问题。结果一个空文件不是考虑的模块。您可以简单地填充它,并导出一些内容使其成为一个模块。
该文件需要从core中添加Component,因此将以下导入添加到顶部
进口{组件}' @angular/核心";