什么"...解析为非模块实体,不能使用此构造导入"是什么意思?

Rya*_*ugh 90 typescript ecmascript-6 es6-modules

我有一些TypeScript文件:

MyClass.ts

class MyClass {
  constructor() {
  }
}
export = MyClass;
Run Code Online (Sandbox Code Playgroud)

MyFunc.ts

function fn() { return 0; }
export = fn;
Run Code Online (Sandbox Code Playgroud)

MyConsumer.ts

import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();
Run Code Online (Sandbox Code Playgroud)

这使我在尝试使用时出错 new

模块"MyClass"解析为非模块实体,无法使用此构造导入.

和试图打电话时 fn()

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

是什么赋予了?

Rya*_*ugh 150

为什么它不起作用

import * as MC from './MyClass';
Run Code Online (Sandbox Code Playgroud)

这是ES6/ES2015风格的import语法.这个的确切含义是"从模块命名空间对象加载./MyClass并在本地使用它MC".值得注意的是,"模块命名空间对象 "仅包含具有属性的普通对象.无法将ES6模块对象作为函数或使用调用new.

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

您从模块中import使用的东西* as X被定义为仅具有属性.在下层的CommonJS中,这可能不完全受到尊重,但TypeScript告诉您标准定义的行为是什么.

什么工作?

您需要使用CommonJS样式的导入语法来使用此模块:

import MC = require('./MyClass');
Run Code Online (Sandbox Code Playgroud)

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

MyClass.ts

export default class MyClass {
  constructor() {
  }
}
Run Code Online (Sandbox Code Playgroud)

MyConsumer.ts

import MC from './MyClass';
Run Code Online (Sandbox Code Playgroud)

我很难过; 规则是愚蠢的.

使用ES6导入语法本来不错,但现在我必须做这import MC = require('./MyClass');件事吗?这是2013年!瘸!但悲伤是编程的一个正常部分.请跳到Kübler-Ross模型的第五阶段:接受.

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

想象未来的自我,尝试运行neato原生ES6模块实现,并通过尝试使用ES6语法来执行ES6明确不做的事情来发现您已经为自己设置了重大故障.

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

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

MyConsumer.ts更改为:

import A from './a';
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在[2.7发行说明](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html)中,在`--esModuleInterop`下,它说"我们强烈建议同时应用它们新项目和现有项目".在我看来,这个答案(以及[FAQ条目/政策](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#should-i-add-an-empty-namespace-to-应该修改在这里链接的"DefinitelyTyped"中的a-package-that-doesnt-export-a-module-to-use-es6-style-imports)以反映新的立场. (5认同)

Mic*_*ael 22

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

所以在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
}
Run Code Online (Sandbox Code Playgroud)

现在你可以使用:

import MyClass from './MyClass';
Run Code Online (Sandbox Code Playgroud)


Sha*_*das 6

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

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

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


NSj*_*nas 5

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

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

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

这最终起作用了:

import debounce from 'debounce' 
Run Code Online (Sandbox Code Playgroud)