Typescript es6 导入模块“文件不是模块错误" [英] Typescript es6 import module "File is not a module error"

查看:66
本文介绍了Typescript es6 导入模块“文件不是模块错误"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 es6 模块语法的 typescript 1.6.

I am using typescript 1.6 with es6 modules syntax.

我的文件是:

test.ts:

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

ma​​in.ts:

import App from './test';

var a = new App.SomeClass();

当我尝试编译 main.ts 文件时,出现此错误:

When I am trying to compile the main.ts file I get this error:

错误 TS2306:文件test.ts"不是模块.

我怎样才能做到这一点?

How can I accomplish that?

推荐答案

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

Extended - to provide more details based on some comments

错误

错误 TS2306:文件test.ts"不是模块.

Error TS2306: File 'test.ts' is not a module.

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

本章解释了 ECMAScript 6 中的内置模块是如何工作的.

17. Modules

This chapter explains how the built-in modules work in ECMAScript 6.

在 ECMAScript 6 中,模块存储在文件中.正好有一个每个文件一个模块,每个模块一个文件.你有两种方式从模块中导出东西.这两种方式可以混合使用,但它是通常最好分开使用.

In ECMAScript 6, modules are stored in files. There is exactly one module per file and one file per module. You have two ways of exporting things from a module. These two ways can be mixed, but it is usually better to use them separately.

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 单个默认导出

可以有一个默认导出.例如一个函数:

There can be a single default export. For example, a function:

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

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

Based on the above we need the export, as a part of the test.js file. Let's adjust the content of it like this:

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

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

And now we can import it with these thre ways:

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

我们可以像这样消费进口的东西:

And we can consume imported stuff like this:

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

并调用该方法以查看其运行情况:

and call the method to see it in action:

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

I would really strongly suggest to check this Q & A:

让我引用第一句话:

...

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

In this case, we just do not need module inside of test.ts. This could be the content of it adjusted test.ts:

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

在这里阅读更多

在前面的示例中,当我们使用每个验证器时,每个模块仅导出一个值.在这种情况下,通过它们的限定名称处理这些符号会很麻烦,而单个标识符也可以这样做.

In the previous example, when we consumed each validator, each module only exported one value. In cases like this, it's cumbersome to work with these symbols through their qualified name when a single identifier would do just as well.

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

The export = syntax specifies a single object that is exported from the module. This can be a class, interface, module, function, or enum. When imported, the exported symbol is consumed directly and is not qualified by any name.

我们以后可以这样消费它:

we can later consume it like this:

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

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

sc.getName();

在此处阅读更多信息:

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

In some cases, you may want to only load a module under some conditions. In TypeScript, we can use the pattern shown below to implement this and other advanced loading scenarios to directly invoke the module loaders without losing type safety.

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

The compiler detects whether each module is used in the emitted JavaScript. For modules that are only used as part of the type system, no require calls are emitted. This culling of unused references is a good performance optimization, and also allows for optional loading of those modules.

该模式的核心思想是 import id = require('...') 语句让我们可以访问外部模块公开的类型.模块加载器是动态调用的(通过 require),如下面的 if 块所示.这利用了引用剔除优化,以便仅在需要时加载模块.为了让这种模式起作用,重要的是通过 import 定义的符号仅用于类型位置(即永远不会在会被发送到 JavaScript 的位置中).

The core idea of the pattern is that the import id = require('...') statement gives us access to the types exposed by the external module. The module loader is invoked (through require) dynamically, as shown in the if blocks below. This leverages the reference-culling optimization so that the module is only loaded when needed. For this pattern to work, it's important that the symbol defined via import is only used in type positions (i.e. never in a position that would be emitted into the JavaScript).

这篇关于Typescript es6 导入模块“文件不是模块错误"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆