TypeScript ES6 导入模块“文件不是模块错误”

2022-08-30 01:49:40

我正在使用TypeScript 1.6和ES6模块语法。

我的文件是:

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”不是模块。

我怎样才能做到这一点?


答案 1

扩展 - 根据一些注释提供更多详细信息

错误

错误 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!

基于上述内容,我们需要导出,作为测试文件的一部分.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())

原始部分试图帮助降低命名空间使用的复杂性

原件:

我真的强烈建议检查这个问答:

如何将命名空间与 TypeScript 外部模块一起使用?

让我引用第一句话:

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

别这样。

认真地。停。

...

在这种情况下,我们只是不需要 里面的模块。这可能是它调整后的内容 test.tstest.ts

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

在此处阅读更多内容

导出 =

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

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

我们以后可以像这样使用它:

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

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

sc.getName();

在此处阅读更多内容:

可选模块加载和其他高级加载方案

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

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

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


答案 2

以上答案是正确的。但为了以防万一...在VS代码中出现相同的错误。必须重新保存/重新编译引发错误的文件。