打字稿 ES6 导入模块 "File is not a module error"



我使用带有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的答案之外,有时即使这样也不起作用,所以你需要:

  1. 使用智能感知重写导入字符串。有时这会修复问题
  2. 重启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/核心";

最新更新