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

时间:2015-09-27 07:24:55

标签: javascript typescript ecmascript-6

我正在使用带有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'不是模块。

我该如何实现?

8 个答案:

答案 0 :(得分:94)

扩展 - 根据一些评论提供更多详细信息

错误

  

错误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";

我们可以使用这样的导入内容:

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&答:

How do I use namespaces with TypeScript external modules?

让我引用第一句话:

  

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

     

不要这样做。

     

严重。停止。

     

...

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

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

在这里阅读更多内容

Export =

  

在前面的示例中,当我们使用每个验证器时,每个模块只导出一个值。在这种情况下,当单个标识符同样适用时,通过其限定名称使用这些符号很麻烦。

     

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

我们可以稍后使用它:

import App = require('./test');

var sc: App.SomeClass = new App.SomeClass();

sc.getName();

在这里阅读更多内容:

Optional Module Loading and Other Advanced Loading Scenarios

  

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

     

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

     

模式的核心思想是import id = require('...')语句使我们能够访问外部模块公开的类型。模块加载器是动态调用的(通过require),如下面的if块所示。这利用了参考剔除优化,因此仅在需要时加载模块。要使此模式起作用,重要的是通过导入定义的符号仅用于类型位置(即从不在将被发送到JavaScript中的位置)。

答案 1 :(得分:8)

我该如何实现?

您的示例声明了一个TypeScript< 1.5 内部模块,现在称为namespace。旧的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();

那就是说......

Try to avoid exporting namespaces而是导出模块(之前称为外部模块)。如果需要,您可以使用namespace import pattern导入时使用命名空间,如下所示:

// test.ts
export class SomeClass {
    getName(): string {
        return 'name';
    }
}

// main.ts
import * as App from './test'; // namespace import pattern
var a = new App.SomeClass();

答案 2 :(得分:7)

以上答案是正确的。但为了以防万一...... VS Code中出现相同的错误。不得不重新保存/重新编译抛出错误的文件。

答案 3 :(得分:2)

除了A. Tim's answer之外,有时候甚至不起作用,因此您需要:

  1. 使用智能感知来重写导入字符串。有时这可以解决问题
  2. 重新启动VS代码

答案 4 :(得分:0)

除了蒂姆的答案,当我拆分一个重构文件,将其拆分成自己的文件时,这个问题对我来说还是发生了。

由于某种原因,VSCode使[class]代码的部分缩进,从而导致了此问题。起初很难注意到这一点,但是当我意识到代码缩进之后,我格式化了代码,问题就消失了。

例如,在粘贴过程中,类定义第一行之后的所有内容都会自动缩进。

export class MyClass extends Something<string> {
    public blah: string = null;

    constructor() { ... }
  }

答案 5 :(得分:0)

我遇到了这个问题,我忘记导出类了。

答案 6 :(得分:0)

以防万一这对你有用,因为它确实形成了我,我有这个文件

//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",

答案 7 :(得分:-1)

文件需要从核心添加组件,因此将以下导入添加到顶部

从'@ angular / core'导入{组件};