typescript - "... resolves to a non-module entity and cannot be imported using this construct"是什么意思?

标签 typescript ecmascript-6 es6-modules

我有一些 TypeScript 文件:

MyClass.ts

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

MyFunc.ts

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

MyConsumer.ts

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

这让我在尝试使用 new

时出错

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

当尝试调用 fn()

Cannot invoke an expression whose type lacks a call signature.

什么给了?

最佳答案

为什么不起作用

import * as MC from './MyClass';

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

再说一遍:ES6 模块命名空间对象不能作为函数调用,也不能用new调用。

您使用 * as X 从模块中导入 的东西被定义为仅具有属性。在低级别的 CommonJS 中,这可能没有得到充分尊重,但 TypeScript 会告诉您标准定义的行为是什么。

什么起作用了?

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

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

如果您同时控制这两个模块,则可以使用export default 代替:

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

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

如果使用 ES6 导入语法会很好,但现在我必须做这个 import MC = require('./MyClass'); 事情?真是2013年了!瘸!但悲伤是编程的正常部分。请跳到 Kübler-Ross 模型中的第五阶段:接受。

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

想象一下你 future 的自己,尝试在 neato 原生 ES6 模块实现上运行,并发现你已经为重大失败做好了准备 尝试使用 ES6 语法来做一些 ES6 明确不做的事情.

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

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

MyConsumer.ts 更改为:

import A from './a';

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

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

关于typescript - "... resolves to a non-module entity and cannot be imported using this construct"是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39415661/

相关文章:

javascript - 在大型 TypeScript 项目中共享类型的最佳方式?

Typescript:以编程方式访问 VS Code 的 "Find All References"

reactjs - Nuka 轮播未在 react 幻灯片高度 Prop 0 中显示

vue.js - 如何更改 v-slider 的大小?

vue.js - 注册Nuxt插件: Globally vs Manual Import

javascript - 从子路由到父路由的 Angular 访问方法

JavaScript 在带有回调的循环中异步

javascript - 过滤数组中对象的值时出现 TypeError : obj[key]. 包含不是函数

d3.js - d3 4.x 的 es6 模块导入失败

javascript - 通过聚合名称或部分名称导入聚合