无法调用或构造名称空间样式的导入,并且会在运行时导致失败

Joh*_*ter 30 express typescript typescript-typings

这里发生了奇怪的事情,使用TypeScript 2.7.2,在带有@ types/express的VSCode版本1.21和随后的代码中,在某些情况下,VSCode会抛出错误,指出"无法调用或构造名称空间样式的导入,并将导致在运行时失败." 但是在具有类似设置和类似tsconfig.json文件的其他机器上,代码才有效..这里发生了什么:

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

let app: Express.Express;
this.app = Express();                <== and here
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

TIA,

约翰.

fat*_*thy 59

该错误应该只发生esModuleInterop: true.也许VSCode忽略了你tsconfig.json或另一个esModuleInterop: true使用的.

对于明确的修复,请将编译器选项设置esModuleInterop为true并使用import express而不是import * as express.

问题:

ES6规范定义了"命名空间对象"的概念.命名空间对象namespaceObject在此语句中:import * as namespaceObject from 'a-module'.在typeof此目标是object,你是不是应该能够调用它.

您使用import * as express到目前为止因为express是CommonJS模块,对于Node.js,它是使用导出的module.exports.但是在ES6规范中它是非法的,TypeScript现在警告你.

解决方案:

设置esModuleInterop为true将使TypeScript包装您的import调用以检查模块是ES6模块还是CommonJS.如果它是CommonJS模块并且您正在使用import default from 'module'TypeScript将查找并返回正确的CommonJS模块.

从TypeScript发行说明:

注意:新行为是在标志下添加的,以避免对现有代码库进行无理中断.我们强烈建议将其应用于新项目和现有项目.对于现有项目,名称空间导入(import*表示来自"express"; express();)将需要转换为默认导入(import express表示"express"; express();).

  • 链接的发行说明中对我帮助最大的那一行是“在新的--esModuleInterop标志下,必须将这些可调用的CommonJS模块作为默认导入导入...”,并举例说明了“ express中的import express”。如果“ allowSyntheticDefaultImports”不是“ true”,这当然会失败,这基本上意味着需要使用该标志才能使用可调用模块。 (3认同)
  • 也帮助我解决了 momentjs 的问题,我使用这种方式导入:`import moment, { Moment } from 'moment';` (2认同)
  • @Chima 你找到解决办法了吗?即使同时启用两者后,它对我来说也失败了? (2认同)
  • @RohitMittal 不幸的是我没有 - 我只是按照要求留下了它 (2认同)

mik*_*ana 21

就我而言,我已经"esModuleInterop": true启用了tsconfig.json. 我需要转换:

import * as assert from "assert";

到:

import assert from "assert";