简体   繁体   English

Node.js + TypeScript:带有类型脚本编译代码的语法不明确

[英]Node.js + TypeScript: Unclear syntax with type script compiled code

I'm trying to work with TypeScript in my node project, but I have some issues with that.我正在尝试在我的节点项目中使用 TypeScript,但是我遇到了一些问题。

This is my index.ts file:这是我的index.ts文件:

import express from 'express';

const app = express();

I'm running:我在跑:

tsc --module commonsjs -d index.ts

My output is index.js :我的输出是index.js

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

Where did this ["default"] came from?这个["default"]来自哪里? It is making my code not to run properly:它使我的代码无法正常运行:

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

TypeError: express_1.default is not a function

As far as I understand, I should have got the code without the "default" brackets and it would have worked fine - I tried removing the brackets and it worked.据我所知,我应该得到没有“默认”括号的代码,它会正常工作 - 我尝试删除括号并且它起作用了。

What am I missing here?我在这里缺少什么?

The safest solution would be:最安全的解决方案是:

import express = require('express');

This transpiles to:这转换为:

var express = require('express');

The official documentation for import require declarations can be found here .可以在此处找到导入需要声明的官方文档。

I believe TypeScript expects an export named "default" to function as your code above, judging from the final paragraph here .我相信 TypeScript 期望一个名为“default”的导出作为你上面的代码,从这里的最后一段判断。


Side note: It looks like TypeScript's newest version (typescript@1.8.0-dev.20151229 at the time of writing) will throw a warning on a compile attempt which would attempt to use a missing default:旁注:看起来 TypeScript 的最新版本(在撰写本文时为 typescript@1.8.0-dev.20151229)会在尝试使用缺少的默认值的编译尝试中抛出警告:

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

Side note 2: An example from Microsoft using the import * as express from 'express';旁注 2:来自 Microsoft 的示例,使用import * as express from 'express'; syntax can be found here .语法可以在这里找到。 When targeting a module of commonjs (as they are in this example), this will also transpile to var express = require('express');当定位的模块commonjs (如它们是在该示例中),这也将transpile到var express = require('express'); . .


If you have at least TypeScript 2.7 and are targeting CommonJS, you can use esModuleInterop , as well.如果你至少有 TypeScript 2.7 并且面向 CommonJS,你也可以使用esModuleInterop

From the link:从链接:

To give users the same runtime behavior as Babel or Webpack, TypeScript provides a new --esModuleInterop flag when emitting to legacy module formats.为了向用户提供与 Babel 或 Webpack 相同的运行时行为,TypeScript 在发送到旧模块格式时提供了一个新的 --esModuleInterop 标志。

Under the new --esModuleInterop flag, these callable CommonJS modules must be imported as default imports like so:在新的 --esModuleInterop 标志下,这些可调用的 CommonJS 模块必须作为默认导入导入,如下所示:

import express from "express";

let app = express();

We strongly suggest that Node.js users leverage this flag with a module target of CommonJS for libraries like Express.js, which export a callable/constructable module.我们强烈建议 Node.js 用户将这个标志与 CommonJS 的模块目标用于像 Express.js 这样的库,它导出一个可调用/可构造的模块。

I solved this by adding the following to tsconfig.json :我通过将以下内容添加到tsconfig.json解决了这个问题:

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

The esModuleInterop flag is described as: "Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility." esModuleInterop标志被描述为:“发出 __importStar 和 __importDefault 帮助程序以实现运行时 babel 生态系统兼容性并启用 --allowSyntheticDefaultImports 以实现类型系统兼容性。”

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

If you are trying to use the default export of a non-ES6 module like Express.js, you need to use the legacy import syntax import express = require('express') .如果您尝试使用 Express.js 等非 ES6 模块的默认导出,则需要使用旧式导入语法import express = require('express')

In ES6 modules, there is no default value export like the module.exports of Node.js modules or the return of AMD modules;在 ES6 模块中,没有像 Node.js 模块的module.exports或 AMD 模块的return那样的默认值导出; the default export of an ES6 module is just the default key. ES6 模块的默认导出只是default键。 This is why, when you use an ES6 default import as you are attempting to do, TypeScript generates JavaScript with an access to the default property.这就是为什么当您尝试使用 ES6 默认import ,TypeScript 会生成具有default属性访问权限的 JavaScript。

More information about this is available at New es6 syntax for importing commonjs / amd modules ie `import foo = require('foo')` .有关此内容的更多信息可在用于导入 commonjs / amd 模块的新 es6 语法中获得,即`import foo = require('foo')`

If you still want to use the import keyword then use it like:如果您仍然想使用import关键字,请使用它:

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

In file tsconfig.json在文件tsconfig.json

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

Thanks to Josh Dando .谢乔什丹多

Another solution that could work for you is do it like this:另一种可能适合您的解决方案是这样做:

import * as express from express;
const app = express();

It should work in the same way.它应该以相同的方式工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM