web-dev-qa-db-ja.com

NodeJS + TypeScript:タイプスクリプトでコンパイルされたコードの構文が不明確

ノードプロジェクトでTypeScriptを使用しようとしていますが、いくつか問題があります。

これは私のindex.tsファイルです:

import express from 'express';

const app = express();

私が実行している:

tsc --module commonsjs -d index.ts

私の出力はindex.jsです:

var express_1 = require('express');
var app = express_1["default"]();

これはどこでしたか["default"] から来た?コードが正しく実行されない原因になっています。

var app = express_1["default"]();
                              ^

TypeError: express_1.default is not a function

私が理解している限り、「デフォルト」の角かっこなしでコードを取得する必要があり、それは正常に機能していました。角かっこを削除してみましたが、機能しました。

ここで何が欠けていますか?

14
Shikloshi

最も安全な解決策は次のとおりです。

_import express = require('express');
_

これは次のように発生します。

_var express = require('express');
_

Import require宣言の公式ドキュメントは ここ にあります。

TypeScriptは、最後の段落 ここ から判断して、「default」という名前のエクスポートが上記のコードとして機能することを期待していると思います。


ちなみに、TypeScriptの最新バージョン(執筆時点では[email protected])は、欠落しているデフォルトを使用しようとするコンパイルの試行時に警告をスローするようです。

_index.ts(1,8): error TS1192: Module '"express"' has no default export.
_

補足2、_import * as express from 'express';_構文を使用したMicrosoftの例は、 ここ にあります。 commonjsのモジュールをターゲットにする場合(この例では これらは のように)、これもvar express = require('express');にトランスパイルされます。


TypeScript 2.7以上を使用していて、commonjsをターゲットにしている場合は、 esModuleInterop も使用できます。

リンクから:

ユーザーにBabelまたはWebpackと同じランタイム動作を提供するために、TypeScriptは、レガシーモジュール形式に出力するときに新しい--esModuleInteropフラグを提供します。

新しい--esModuleInteropフラグの下で、これらの呼び出し可能なCommonJSモジュールは、次のようにデフォルトのインポートとしてインポートする必要があります。

_import express from "express";

let app = express();
_

Node.jsユーザーは、呼び出し可能/構築可能なモジュールをエクスポートするexpressなどのライブラリのcommonjsのモジュールターゲットでこのフラグを活用することを強くお勧めします。

29
dvlsg

tsconfig.jsonに以下を追加することで、これを解決しました。

{
  "compilerOptions": {
    ... 
    "module": "commonjs",
    "esModuleInterop": true,
    ...
  }
}

esModuleInteropフラグは、「ランタイムbabelエコシステムの互換性のために__importStarおよび__importDefaultヘルパーを発行し、型システムの互換性のために--allowSyntheticDefaultImportsを有効にする」と説明されています。

https://www.typescriptlang.org/docs/handbook/compiler-options.html

12
Liam

Expressなどの非ES6モジュールのデフォルトのエクスポートを使用しようとしている場合は、従来のインポート構文import express = require('express')を使用する必要があります。 ES6モジュールでは、Node.jsモジュールのmodule.exportsやAMDモジュールのreturnのようなデフォルト値のエクスポートはありません。 ES6モジュールのデフォルトのエクスポートは、defaultキーだけです。これが、ES6のデフォルトのimportを使用しようとしているときに、TypeScriptがdefaultプロパティへのアクセス権を持つJavaScriptを生成する理由です。

これについての詳細は commonjs/AMDモジュールをインポートするための新しいes6構文、つまり `import foo = require( 'foo')` で入手できます。

7
C Snover

それでもimportキーワードを使用したい場合は、次のように使用してください

import express from "express"; 
// if above is not supported by your project environment then follow as below
import * as express from "express";

tsconfig.json

{
  "compilerOptions": {
    ...   
    "module": "commonjs"
    ...
  }
}

@JoshDandoに感謝します

2
WasiF