“...解析为非模块实体并且无法使用此构造导入”是什么意思?
What does "... resolves to a non-module entity and cannot be imported using this construct" mean?
我有一些 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-style import
语法。这句话的确切含义是"Take the module namespace object loaded from ./MyClass
and use it locally as MC
"。值得注意的是,"module namespace object" 仅包含一个具有属性的普通对象。 ES6 模块对象不能作为函数调用或使用 new
.
再说一遍:ES6 模块命名空间对象不能作为函数调用或使用 new
.
您 import
使用模块中的 * 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
声明是一种假装有效的流行方式),它们 可能 今天在您特定的降级模块捆绑器中工作(例如汇总),但这是虚幻的。目前还没有任何 ES6 模块实现,但不会永远如此。
想象一下你未来的自己,尝试 运行 在 neato 原生 ES6 模块实现上发现你已经通过 尝试使用 ES6 语法来做某事而为重大失败做好准备ES6 明确不做 .
我想利用我的非标准模块加载器
也许您有一个模块加载器 "helpfully" 在 none 存在时创建 default
导出。我的意思是,人们制定标准是有原因的,但有时忽略标准很有趣,我们可以认为这是一件很酷的事情。
将MyConsumer.ts改为:
import A from './a';
并指定 allowSyntheticDefaultImports
命令行或 tsconfig.json
选项。
请注意,allowSyntheticDefaultImports
根本不会更改代码的 运行 时间行为。它只是一个标志,告诉 TypeScript 你的模块加载器在 none 存在时创建 default
导出。它不会神奇地让你的代码在 nodejs 中工作,而以前没有。
在这里加上我的 2 美分,以防其他人遇到这个问题。
我在不修改 tsconfig.json
的情况下解决问题的方法(这在某些项目中可能会出现问题),我只是简单地禁用了 oneline 的规则。
import MC = require('./MyClass'); // tslint:disable-line
我在尝试在我的项目中包含 npm debounce 包时遇到此错误。
当我尝试上面接受的解决方案时出现异常:
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.
这最终成功了:
import debounce from 'debounce'
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
所以在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
}
现在您可以使用:
import MyClass from './MyClass';
我有一些 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-style import
语法。这句话的确切含义是"Take the module namespace object loaded from ./MyClass
and use it locally as MC
"。值得注意的是,"module namespace object" 仅包含一个具有属性的普通对象。 ES6 模块对象不能作为函数调用或使用 new
.
再说一遍:ES6 模块命名空间对象不能作为函数调用或使用 new
.
您 import
使用模块中的 * 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
声明是一种假装有效的流行方式),它们 可能 今天在您特定的降级模块捆绑器中工作(例如汇总),但这是虚幻的。目前还没有任何 ES6 模块实现,但不会永远如此。
想象一下你未来的自己,尝试 运行 在 neato 原生 ES6 模块实现上发现你已经通过 尝试使用 ES6 语法来做某事而为重大失败做好准备ES6 明确不做 .
我想利用我的非标准模块加载器
也许您有一个模块加载器 "helpfully" 在 none 存在时创建 default
导出。我的意思是,人们制定标准是有原因的,但有时忽略标准很有趣,我们可以认为这是一件很酷的事情。
将MyConsumer.ts改为:
import A from './a';
并指定 allowSyntheticDefaultImports
命令行或 tsconfig.json
选项。
请注意,allowSyntheticDefaultImports
根本不会更改代码的 运行 时间行为。它只是一个标志,告诉 TypeScript 你的模块加载器在 none 存在时创建 default
导出。它不会神奇地让你的代码在 nodejs 中工作,而以前没有。
在这里加上我的 2 美分,以防其他人遇到这个问题。
我在不修改 tsconfig.json
的情况下解决问题的方法(这在某些项目中可能会出现问题),我只是简单地禁用了 oneline 的规则。
import MC = require('./MyClass'); // tslint:disable-line
我在尝试在我的项目中包含 npm debounce 包时遇到此错误。
当我尝试上面接受的解决方案时出现异常:
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.
这最终成功了:
import debounce from 'debounce'
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
所以在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
}
现在您可以使用:
import MyClass from './MyClass';