1. ホーム
  2. ジャバスクリプト

[解決済み] Typescript es6 import module "File is not a module error".

2022-03-04 05:09:44

質問

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' はモジュールではありません。

どうすれば実現できるのでしょうか?

どのように解決するのですか?

拡張 - コメントに基づいて、より詳細な情報を提供するために

エラーについて

<ブロッククオート

エラーTS2306。ファイル 'test.ts' はモジュールではありません。

ここに記載されている事実に起因する http://exploringjs.com/es6/ch_modules.html

<ブロッククオート

17. モジュール

この章では、ECMAScript 6 の組み込みモジュールがどのように動作するかを説明します。

17.1 概要

ECMAScript 6 では、モジュールはファイルに格納されます。ちょうど1つの モジュールと、1つのモジュールに1つのファイルです。次の2つの方法があります。 モジュールから何かをエクスポートする。この2つの方法は混ぜて使うこともできますが 通常は別々に使用したほうがよいでしょう。

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 デフォルトの単一エクスポート

デフォルトのエクスポートは1つだけとすることができる。例えば、関数です。

//------ 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';
    }
  }
}

そして、この3つの方法でインポートすることができるようになりました。

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&Aをぜひご覧ください。

TypeScriptの外部モジュールで名前空間を使用するには?

最初の文章を引用させていただきます。

<ブロッククオート

外部モジュールで "namespaces" を使用しないでください。

これはやめましょう。

マジで。やめてくれ。

...

この場合、単に module の中にある test.ts . これは調整されたそれの内容である可能性があります test.ts :

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

詳しくはこちら

輸出 =

<ブロッククオート

先ほどの例では、各バリデータを消費する際に、各モジュールは1つの値だけをエクスポートしていました。このような場合、単一の識別子で十分なときに、修飾名を通してこれらのシンボルを操作するのは面倒です。

を使用します。 export = 構文では モジュールからエクスポートされる単一のオブジェクトです。 . これは、クラス、インターフェース、モジュール、関数、または列挙型のいずれかになります。インポートされた場合、エクスポートされたシンボルは直接消費され、いかなる名前によっても修飾されません。

のように、後で消費することができます。

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

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

sc.getName();

詳しくはこちらをご覧ください。

オプションのモジュールロードとその他の高度なロードシナリオ

場合によっては、ある条件下でのみモジュールをロードしたいことがあります。TypeScriptでは、以下に示すパターンを使って、このような高度なロードシナリオを実装し、型安全性を失わずにモジュールローダを直接呼び出すことができます。

コンパイラは、生成されたJavaScriptで各モジュールが使用されているかどうかを検出します。型システムの一部としてのみ使用されるモジュールについては、require 呼び出しは実行されません。このように未使用の参照を排除することは、パフォーマンスの最適化であり、また、それらのモジュールのロードを任意に行うことも可能です。

このパターンの核となる考え方は、import id = require('...') ステートメントによって、外部モジュールが公開する型にアクセスできるようになるということです。モジュールローダーは、以下のifブロックに示すように、(requireを通じて)動的に呼び出されます。これは参照カリングの最適化を利用し、必要なときだけモジュールがロードされるようにします。このパターンが機能するためには、import で定義されたシンボルは型の位置でのみ使用されることが重要です(つまり、JavaScript に出力される位置では決して使用されません)。