web-dev-qa-db-ja.com

「...は非モジュールエンティティに解決され、この構造を使用してインポートできない」とはどういう意味ですか?

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()を呼び出そうとしたとき

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

何が得られますか?

88
Ryan Cavanaugh

なぜ機能しないのか

import * as MC from './MyClass';

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

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

モジュールから* as Xを使用してimportするものは、プロパティのみを持つように定義されています。ダウンレベルのCommonJSでは、これは完全に尊重されない場合がありますが、TypeScriptは標準で定義されている動作が何であるかを示しています。

何が機能しますか?

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

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

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

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

私はこれについて悲しいです。ルールは愚かです。

ES6のインポート構文を使用するのは良かったのですが、今ではこのimport MC = require('./MyClass');を実行する必要がありますか? 2013年です!ラメ!しかし、悲嘆はプログラミングの通常の部分です。 Kübler-Rossモデルの承認:ステージ5にジャンプしてください。

ここのTypeScriptは、これが機能しないため、機能しないことを伝えています。ハックがあり(namespace宣言をMyClassに追加することは、この動作のふりをする一般的な方法です)、それらはmight特定のダウンレベリングモジュールバンドルで動作します(たとえば、ロールアップ)が、これは幻想です。まだES6モジュールの実装はまだありませんが、それは永遠に真実ではありません。

将来の自分を想像して、ネイトのネイティブES6モジュールの実装で実行しようとし、ES6構文を使用してES6が明示的にしないことを試みることで、重大な障害に備えていることを見つけますt do

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

たぶん、もし存在しないときにdefaultエクスポートを「助けて」作成するモジュールローダーがあるでしょう。つまり、人々は何らかの理由で標準を作成しますが、標準を無視するのは時々楽しいことです。

MyConsumer.tsを次のように変更します。

import A from './a';

そして、allowSyntheticDefaultImportsコマンドラインまたはtsconfig.jsonオプションを指定します。

allowSyntheticDefaultImportsは、コードの実行時の動作をまったく変更しないことに注意してください。これは、存在しない場合にモジュールローダーがdefaultエクスポートを作成することをTypeScriptに通知する単なるフラグです。以前はなかったのに、nodejsでコードが魔法のように動作することはありません。

149
Ryan Cavanaugh

TypeScript 2.7は、新しいヘルパーメソッドを発行することでサポートを導入します。 https://www.typescriptlang.org/docs/handbook/release-notes/TypeScript-2-7.html#support-for-import-d-from- cjs-form-commonjs-modules-with --- esmoduleinterop

そのため、tsconfig.jsonに次の2つの設定を追加します。

{
    // Enable support for importing CommonJS modules targeting es6 modules
    "esModuleInterop": true,

    // When using above interop will get missing default export error from type check since
    // modules use "export =" instead of "export default", enable this to ignore errors.
    "allowSyntheticDefaultImports": true
}

そして今、あなたは使用することができます:

import MyClass from './MyClass';
21
Michael

ここに私の2セントを追加すると、他の誰かがこの問題を抱えていることになります。

tsconfig.json(一部のプロジェクトでは問題になる可能性があります)を変更せずに問題を回避する私の方法は、onelineのルールを無効にするだけです。

import MC = require('./MyClass'); // tslint:disable-line

4
Shahar Hadas

プロジェクトにnpm debounceパッケージを含めようとすると、このエラーが発生しました。

上記の受け入れられた解決策を試したときに、例外が発生しました。

ECMAScriptモジュールを対象とする場合、インポート割り当ては使用できません。代わりに「import * as ns from "mod"」、「import {a} from "mod"」、「import d from "mod"」、または別のモジュール形式を代わりに使用することを検討してください。

これは機能しました:

import debounce from 'debounce' 
4
NSjonas