typescript 无法调用或构造命名空间样式的导入,并且会导致运行时失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49256040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A namespace-style import cannot be called or constructed, and will cause a failure at runtime
提问by John Gorter
Strange stuff happening here, with TypeScript 2.7.2, in VSCode version 1.21 with @types/express and the code that follows, in some cases VSCode throws errors stating that "A namespace-style import cannot be called or constructed, and will cause a failure at runtime.". However on other machines with similar setups and similar tsconfig.json files the code just works.. What is happening here:
这里发生了一些奇怪的事情,在 TypeScript 2.7.2 中,在 VSCode 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
Why is this happening?
为什么会这样?
TIA,
TIA,
John.
约翰。
回答by fathy
The error should only happen with esModuleInterop: true
. Maybe VSCode is ignoring your tsconfig.json
or another one with esModuleInterop: true
is used.
错误应该只发生在esModuleInterop: true
. 也许 VSCode 忽略了你的tsconfig.json
或另一个esModuleInterop: true
使用的。
For a definitive fix set the compiler option esModuleInterop
to true
and use import express
instead of import * as express
.
对于最终解决设定的编译器选项esModuleInterop
,以true
和使用import express
代替import * as express
。
The problem:
问题:
The ES6 specification defines the notion of "namespace object". A namespace object is namespaceObject
in this statement : import * as namespaceObject from 'a-module'
. The typeof
this object is object
, you are not supposed to be able to call it.
ES6 规范定义了“命名空间对象”的概念。Namespace对象是namespaceObject
在此声明:import * as namespaceObject from 'a-module'
。在typeof
此目标是object
,你是不是应该能够调用它。
You were using import * as express
until now because express
is a CommonJS module, for Node.js, it is exported using module.exports
. However it is illegal in the ES6 spec, and TypeScript now warns you.
您一直使用import * as express
到现在是因为它express
是一个 CommonJS 模块,对于 Node.js,它是使用module.exports
. 然而,它在 ES6 规范中是非法的,TypeScript 现在会警告你。
The solution:
解决办法:
Setting esModuleInterop
to true will make TypeScript wrap your import
calls to check if the module is an ES6 module or a CommonJS. If it's a CommonJS module and you are using import default from 'module'
TypeScript will find out and return the correct CommonJS module.
设置esModuleInterop
为 true 将使 TypeScript 包装您的import
调用以检查模块是 ES6 模块还是 CommonJS。如果它是一个 CommonJS 模块,并且你正在使用import default from 'module'
TypeScript 会找出并返回正确的 CommonJS 模块。
From the TypeScript release note:
从打字稿发行说明:
Note: The new behavior is added under a flag to avoid unwarranted breaks to existing code bases. We highly recommend applying it both to new and existing projects. For existing projects, namespace imports (import * as express from "express"; express();) will need to be converted to default imports (import express from "express"; express();).
注意:新行为添加在一个标志下,以避免对现有代码库造成不必要的破坏。我们强烈建议将其应用于新项目和现有项目。对于现有项目,命名空间导入(import * as express from "express"; express();)需要转换为默认导入(import express from "express"; express();)。