我有一些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
模块" MyClass"解析为非模块实体,无法使用此结构导入。
并尝试拨打fn()
无法调用类型缺少调用签名的表达式。
是什么给出了?
答案 0 :(得分:147)
import * as MC from './MyClass';
这是ES6 / ES2015风格的import
语法。其确切含义是“从./MyClass
加载模块名称空间对象,并在本地将其用作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告诉你这不起作用,因为它不起作用。有一些黑客(向namespace
添加MyClass
声明是一种流行的方式来假装这种方法),并且他们可能今天在你的特定下层模块捆绑器中工作(例如汇总) ,但这是虚幻的。野外还没有任何ES6模块实现,但这不会永远是真的。
想象未来的自我,尝试运行neato原生ES6模块实现,并发现你已经为尝试使用ES6语法执行ES6明确不做的事情而为重大失败做好准备< / em>的
也许你有一个模块加载器,当不存在时,“帮助”创建default
导出。我的意思是,人们制定标准是有原因的,但忽略标准有时很有趣,我们可以认为这很酷。
将 MyConsumer.ts 更改为:
import A from './a';
并指定allowSyntheticDefaultImports
命令行或tsconfig.json
选项。
请注意,allowSyntheticDefaultImports
根本不会更改代码的运行时行为。它只是一个标志告诉TypeScript你的模块加载器在不存在时创建default
导出。它不会神奇地使你的代码在nodejs中工作,而不是之前。
答案 1 :(得分:20)
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';
答案 2 :(得分:4)
在这里加上我的2美分,因为别人有这个问题。
我在不修改tsconfig.json
的情况下处理这个问题的方式(在某些项目中可能会有问题),我只是简单地禁用了oneline规则。
import MC = require('./MyClass'); // tslint:disable-line
答案 3 :(得分:4)
尝试在我的项目中包含npm debounce包时出现此错误。
当我尝试上面接受的解决方案时,我得到了一个例外:
定位ECMAScript模块时无法使用导入分配。 考虑使用&#39; import *作为来自&#34; mod&#34;&#39;,&#39;导入{a}来自&#34; mod&#34;&#39;, &#39;从&#34; mod&#34;&#39;或其他模块格式导入d。
这最终起作用了:
sed -i 's|1006\.2|Irradiance (W/m^2) &|g' file1.1