web-dev-qa-db-ja.com

名前空間スタイルのインポートは呼び出すことも構築することもできず、実行時にエラーが発生します

TypeScript 2.7.2、VSTypeバージョン1.21、@ types/expressおよびそれに続くコードでここで発生する奇妙なことは、場合によってはVSCodeが「名前空間スタイルのインポートを呼び出したり構築したりできず、実行時の失敗。」。ただし、同様のセットアップと同様のtsconfig.jsonファイルを持つ他のマシンでは、コードは機能します。ここで何が起こっているのか:

import { Bank } from './Bank';
import * as Express from 'express';  <== errors here..

let app: Express.Express;
this.app = Express();                <== and here

なぜこうなった?

TIA、

ジョン。

27
John Gorter

エラーはesModuleInterop: trueでのみ発生します。おそらくVSCodeはtsconfig.jsonを無視しているか、esModuleInterop: trueを持つ別のコードが使用されています。

決定的な修正を行うには、コンパイラオプションesModuleInteroptrueに設定し、import expressの代わりにimport * as expressを使用します。

問題

ES6仕様は、「名前空間オブジェクト」の概念を定義しています。名前空間オブジェクトは、このステートメントのnamespaceObjectです:import * as namespaceObject from 'a-module'typeofこのオブジェクトはobjectです。これを呼び出すことはできません。

expressはCommonJSモジュールであるため、これまでimport * as expressを使用していました。Node.jsでは、module.exportsを使用してエクスポートされます。ただし、ES6仕様では違法であり、TypeScriptは警告を表示します。

解決策

esModuleInteropをtrueに設定すると、TypeScriptはimport呼び出しをラップして、モジュールがES6モジュールまたはCommonJSかどうかを確認します。 CommonJSモジュールであり、import default from 'module'を使用している場合、TypeScriptは正しいCommonJSモジュールを見つけて返します。

TypeScriptリリースノート から:

注:既存のコードベースへの不当な中断を避けるために、新しい動作がフラグの下に追加されます。新規および既存のプロジェクトの両方に適用することを強くお勧めします。既存のプロジェクトの場合、名前空間のインポート(「エクスプレス」からのエクスプレス*;エクスプレス();)をデフォルトのインポート(「エクスプレス」からのエクスプレスエクスプレス;エクスプレス();)に変換する必要があります。

57
fathy