typescript “...解析为非模块实体并且无法使用此构造导入”是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39415661/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:19:35  来源:igfitidea点击:

What does "... resolves to a non-module entity and cannot be imported using this construct" mean?

typescriptecmascript-6es6-modules

提问by Ryan Cavanaugh

I have some TypeScript files:

我有一些 TypeScript 文件:

MyClass.ts

MyClass.ts

class MyClass {
  constructor() {
  }
}
export = MyClass;

MyFunc.ts

MyFunc.ts

function fn() { return 0; }
export = fn;

MyConsumer.ts

我的消费者.ts

import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();

This gives me errors when trying to use new

这在尝试使用时给了我错误 new

Module "MyClass" resolves to a non-module entity and cannot be imported using this construct.

模块“MyClass”解析为非模块实体,无法使用此构造导入。

and when trying to call fn()

当试图打电话时 fn()

Cannot invoke an expression whose type lacks a call signature.

无法调用类型缺少调用签名的表达式。

What gives?

是什么赋予了?

回答by Ryan Cavanaugh

Why it doesn't work

为什么它不起作用

import * as MC from './MyClass';

This is ES6/ES2015-style importsyntax. The exact meaning of this is "Take the module namespace objectloaded from ./MyClassand use it locally as MC". Notably, the "module namespace object" consists only of a plain object with properties. An ES6 module object cannot be invoked as a function or with new.

这是 ES6/ES2015 风格的import语法。这的确切含义是“获取从中加载的模块命名空间对象./MyClass并在本地使用它作为MC”。值得注意的是,“模块命名空间对象”仅由具有属性的普通对象组成。ES6 模块对象不能作为函数或使用new.

To say it again: An ES6 module namespace object cannot be invoked as a function or with new.

再说一遍:ES6 模块命名空间对象不能作为函数或使用new.

The thing you importusing * as Xfrom a module is defined to only have properties. In downleveled CommonJS this might not be fully respected, but TypeScript is telling you what the behavior defined by the standard is.

您从模块中import使用的东西* as X被定义为只有属性。在较低级别的 CommonJS 中,这可能不会得到完全尊重,但 TypeScript 会告诉您标准定义的行为是什么。

What does work?

有什么作用?

You'll need to use the CommonJS-style import syntax to use this module:

你需要使用 CommonJS 风格的导入语法来使用这个模块:

import MC = require('./MyClass');

If you control both modules, you can use export defaultinstead:

如果您控制两个模块,则可以使用export default

MyClass.ts

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

我的消费者.ts

import MC from './MyClass';

I'm Sad About This; Rules are Dumb.

我为此感到难过;规则是愚蠢的。

It would have been nice to use ES6 import syntax, but now I have to do this import MC = require('./MyClass');thing? It's so 2013! Lame! But grief is a normal part of programming. Please jump to stage five in the Kübler-Ross model: Acceptance.

使用 ES6 导入语法会很好,但现在我必须做这import MC = require('./MyClass');件事?2013年就是这样!瘸!但悲伤是编程的正常部分。请跳到库伯勒-罗斯模型的第五阶段:接受。

TypeScript here is telling you this doesn't work, because it doesn't work. There are hacks (adding a namespacedeclaration to MyClassis a popular way to pretend this works), and they mightwork today in your particular downleveling module bundler (e.g. rollup), but this is illusory. There aren't any ES6 module implementations in the wild yet, but that won't be true forever.

这里的 TypeScript 告诉你这行不通,因为它行不通。有一些黑客(添加namespace声明MyClass是一种流行的方式来假装它有效),它们今天可能在您特定的下层模块捆绑器(例如汇总)中有效,但这是虚幻的。目前还没有任何 ES6 模块实现,但不会永远如此。

Picture your future self, trying to run on a neato native ES6 module implementation and finding that you've set yourself up for major failure by trying to use ES6 syntax to do something that ES6 explicitly doesn't do.

想象一下你未来的自己,尝试在一个neato原生 ES6 模块实现上运行,并发现你已经通过尝试使用 ES6 语法来做一些 ES6 明确没有做的事情,从而为重大失败做好准备

I want to take advantage of my non-standard module loader

我想利用我的非标准模块加载器

Maybe you have a module loader that "helpfully" creates defaultexports when none exist. I mean, people make standards for a reason, but ignoring standards is fun sometimes and we can think that's a cool thing to do.

也许您有一个模块加载器,它可以default在不存在导出时“帮助”创建导出。我的意思是,人们制定标准是有原因的,但有时忽略标准很有趣,我们可以认为这是一件很酷的事情。

Change MyConsumer.tsto:

MyConsumer.ts更改为:

import A from './a';

And specify the allowSyntheticDefaultImportscommand-line or tsconfig.jsonoption.

并指定allowSyntheticDefaultImports命令行或tsconfig.json选项。

Note that allowSyntheticDefaultImportsdoesn't change the runtime behavior of your code at all. It's just a flag that tells TypeScript that your module loader creates defaultexports when none exist. It won't magically make your code work in nodejs when it didn't before.

请注意,这allowSyntheticDefaultImports根本不会改变代码的运行时行为。它只是一个标志,告诉 TypeScript 你的模块加载器default在不存在时创建导出。它不会神奇地让您的代码在 nodejs 中工作,而以前没有。

回答by Michael

TypeScript 2.7 introduces support by emitting new helper methods: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form-commonjs-modules-with---esmoduleinterop

TypeScript 2.7 通过发出新的辅助方法引入支持:https: //www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-with---esmoduleinterop

So in tsconfig.json add these two settings:

所以在 tsconfig.json 添加这两个设置:

{
    // Enable support for importing CommonJS modules targeting es6 modules
    "esModuleInterop": true,

    // When using above interop will get missing default export error from type check since
    // modules use "export =" instead of "export default", enable this to ignore errors.
    "allowSyntheticDefaultImports": true
}

And now you can use:

现在您可以使用:

import MyClass from './MyClass';

回答by Shahar Hadas

Adding my 2 cents here incase someone else have this issue.

在这里添加我的 2 美分以防其他人遇到此问题。

My way of working around the issue without modifying tsconfig.json(which can be problematic in some projects), I've gone with simply disabling the rule for oneline.

我在不修改的情况下解决这个问题的方式tsconfig.json(这在某些项目中可能会出现问题),我已经简单地禁用了 oneline 的规则。

import MC = require('./MyClass'); // tslint:disable-line

import MC = require('./MyClass'); // tslint:disable-line

回答by NSjonas

I got this error when trying to include a npm debounce package in my project.

尝试在我的项目中包含 npm debounce 包时出现此错误。

When I tried the accepted solution above I got an exception:

当我尝试上面接受的解决方案时,我得到了一个例外:

Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

以 ECMAScript 模块为目标时不能使用导入分配。考虑使用 'import * as ns from "mod"'、'import {a} from "mod"'、'import d from "mod"' 或其他模块格式。

This ended up working:

这最终起作用了:

import debounce from 'debounce'