1. ホーム
  2. typescript

[解決済み] ...は非モジュールのエンティティに解決され、このコンストラクトを使用してインポートすることはできません」とはどういう意味ですか?

2023-02-20 19:55:55

質問

TypeScriptのファイルがいくつかあります。

MyClass.ts

class MyClass {
  constructor() {
  }
}
export = MyClass;

MyFunc.ts

function fn() { return 0; }
export = fn;

MyConsumer.ts

import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();

を使おうとすると、エラーが発生します。 new

モジュール "MyClass"は非モジュールのエンティティに解決され、この構成を使用してインポートすることはできません。

を呼び出そうとすると fn()

型が呼び出し署名を持たない式を呼び出すことはできません。

どうしたんですか?

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

なぜ動作しないのか

import * as MC from './MyClass';

これはES6/ES2015スタイルの import の構文です。正確な意味は、"モジュールを取る 名前空間オブジェクト からロードされた ./MyClass としてローカルに使用します。 MC とすることができます。注目すべきは、"モジュールの 名前空間オブジェクト は、プロパティを持つプレーンなオブジェクトのみから構成されています。ES6 モジュールオブジェクトは関数として呼び出すことはできません。 new .

もう一度言う。 ES6 モジュール名前空間オブジェクトは、関数として呼び出すことはできません。 new .

あなたが import を使って * as X を使用すると、モジュールからプロパティのみを持つように定義されています。下位のCommonJSでは、これは完全に尊重されないかもしれませんが、TypeScriptは、標準によって定義された動作が何であるかを教えてくれているのです。

何が動作するのか?

このモジュールを使用するには、CommonJSスタイルのインポート構文を使用する必要があります。

import MC = require('./MyClass');

両方のモジュールを制御する場合は export default を代わりに使うことができます。

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

これは悲しい。ルールは馬鹿だ。

ES6のimport構文が使えればよかったのですが、今はこのように import MC = require('./MyClass'); のようなことをしなければならないのですか?2013年らしい! ダサい! しかし、悲しみはプログラミングの正常な部分です。キューブラー・ロスモデルの第五段階にジャンプしてください。受け入れることです。

このTypeScriptは、これはうまくいかないと伝えています。ハックがあります( namespace の宣言を MyClass は、これが機能するふりをするための一般的な方法です)、そして、彼らは は今日、あなたの特定のダウンレベルモジュールバンドル (例: rollup) で動作するかもしれませんが、これは幻想です。まだ野生の ES6 モジュールの実装はありませんが、それは永久に真実ではありません。

未来の自分を想像してみてください。素敵なネイティブ ES6 モジュール実装で実行しようとして、次のような理由で大失敗することを発見したのです。 ES6 が明示的に行わないことを行うために ES6 の構文を使用しようとしている。 .

非標準のモジュールローダを活用したい

もしかしたら、モジュールローダーが、quot;helpful" で default エクスポートを作成するモジュール ローダーがあるかもしれません。つまり、人々は理由のために標準を作りますが、標準を無視することは時に楽しく、それを行うことがクールなことだと考えることができるのです。

変更点 MyConsumer.ts に変更します。

import A from './a';

と指定し allowSyntheticDefaultImports コマンドラインまたは tsconfig.json オプションで指定します。

なお、この allowSyntheticDefaultImports はコードの実行時の挙動を全く変えないことに注意してください。これは単なるフラグで、TypeScriptにモジュールローダーが default を作成することを TypeScript に伝えるフラグである。以前は動作しなかったコードが、魔法のようにnodejsで動作するようになるわけではありません。