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


93

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

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

何ができますか?


2
答えを共有してくれてありがとう。ここでのプライマリタグはなので、プライマリタグjavascriptとして削除してそのままにすることをお勧めします。質問が間違っていることを前提とし(TS機能は)とペアにすることができる一方で、それはとペアにする必要があります。基本的には、ES6モジュールのインポート/エクスポートとCJS / AMDです。ecmascript-6typescriptexport =import ... fromimport =
Estus Flask 2016

回答:


156

機能しない理由

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 MC = require('./MyClass');ますか?2013年だよ!ラメ!しかし、悲嘆はプログラミングの通常の部分です。キュブラーロスモデルのステージ5に進んでください。

ここのTypeScriptは、これが機能しないため、機能しないことを通知しています。ハックがあり(namespace宣言を追加することMyClassは、この動作を装う一般的な方法です)、特定のダウンレベリングモジュールバンドル(ロールアップなど)で動作する可能性がありますが、これは幻想です。ES6モジュールの実装はまだ出回っていませんが、いつまでも真実ではありません。

ES6構文を使用してES6が明示的に実行しないことを実行しようとすることで、neatoネイティブES6モジュール実装で実行しようとし、重大な障害に備えていることを確認して、将来の自分を想像してください

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

多分あなたはdefault何も存在しないときにエクスポートを「うまく」作成するモジュールローダーを持っています。つまり、人々は理由のために標準を作成しますが、標準を無視するのは楽しいこともあります。

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

import A from './a';

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

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


commonjsスタイルはcommonjsターゲットを必要としませんか?es6 / es2015をターゲットにしているときに、これを機能させる方法はありますか?
Steve Buzonas 2017年

ES6 では機能しないため、 ES6をターゲットにして機能させることはできません...
Ryan Cavanaugh

ES2015モジュールを対象としている場合、CommonJSモジュールを参照する方法がないことは理解できexport = MyClassますか?私の唯一のオプションは、モジュールをに設定し、commonjs最新のESを使用しないことで世界をさらに悪化させ続けることですか?
Micah Zoltu

6
では2.7リリースノート、下に--esModuleInterop、それは「我々は非常に新規および既存のプロジェクトに両方を適用するお勧めします」と言います。私の意見では、この回答(およびここにあるリンクのFAQエントリ/ポリシーDefinitelyTyped)は、新しいスタンスを反映するように変更する必要があります。
Alec Mev

1
とてもとても生意気です。
jmealy 2018

25

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

esModuleInterop私が使用する代わりに、使用に関するresolveJsonModule他の提案を併用しましたがallowSyntheticDefaultImports、それは私にとってはうまくいきました。
Edgar Quintero

6

他の誰かがこの問題を抱えている場合に備えて、ここに2セントを追加します。

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

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


5

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

上記の承認された解決策を試したところ、例外が発生しました:

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

これはうまくいきました:

import debounce from 'debounce' 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.