【问题标题】:A namespace-style import cannot be called or constructed, and will cause a failure at runtime命名空间风格的导入不能被调用或构造,会导致运行时失败
【发布时间】:2018-08-21 16:50:12
【问题描述】:

对于 TypeScript 2.7.2,在带有 @types/express 和随后代码的 VSCode 版本 1.21 中,在某些情况下 VSCode 会抛出错误说明

A namespace-style import cannot be called or constructed, and will cause a failure at runtime.

但是,在其他具有类似设置和类似tsconfig.json 文件的机器上,该代码可以正常工作。这里发生了什么...

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

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

为什么会这样?

TIA,

约翰。

【问题讨论】:

  • 除了@fathyb 的回答之外,您可能还需要在tsconfig.json 中启用allowSyntheticDefaultImports

标签: typescript express typescript-typings


【解决方案1】:

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

要进行最终修复,请将编译器选项 esModuleInterop 设置为 true 并使用 import express 而不是 import * as express

问题

ES6 规范定义了“命名空间对象”的概念。命名空间对象在此语句中为 namespaceObjectimport * 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 release note

注意:新行为被添加在一个标志下,以避免不必要的 打破现有的代码库。我们强烈建议将其同时应用于 新项目和现有项目。对于现有项目,命名空间导入 (import * as express from "express"; express();) 需要 转换为默认进口(从“快递”进口快递; 表达();)。

【讨论】:

  • 链接的发行说明中对我帮助最大的一行是“在新的 --esModuleInterop 标志下,这些可调用的 CommonJS 模块必须作为默认导入...”,并以 @ 为例987654339@。如果allowSyntheticDefaultImports 不是true,这当然会失败,这基本上意味着使用可调用模块需要该标志。
  • 谢谢。我在使用momentjs 时遇到了这些错误,而您的回答正是我所需要的。
  • 帮助我解决了 momentjs 的问题,我使用 import 这种方式:import moment, { Moment } from 'moment';
  • 不知何故我仍然收到以下两个"esModuleInterop": true, "allowSyntheticDefaultImports": true的错误任何想法?
  • @RohitMittal 不幸的是我没有 - 我只是按要求留下了它
【解决方案2】:

这个怎么样:

import express = require('express');

很奇怪,但它有效

【讨论】:

    【解决方案3】:

    在我的情况下,我已经启用了 "esModuleInterop": true,tsconfig.json,我需要转换:

    import * as assert from "assert";

    到:

    import assert from "assert";

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      相关资源
      最近更新 更多