出现错误:如何从 typescript 正确使用我的转译和类型化的 typescript npm 模块?

Getting errors: How can I properly consume my transpiled and typed typescript npm module from typescript?

giving a shot at typescript. I've written a trivial "hello world" typescript module and published it to npm。真的很简单,只是做一个默认导出:

export default function hello(target: string = 'World'): void
{
    console.log(`Hello, ${target} :-(`)
}

node.js 0.10 -> 6 消耗得非常好。 该模块在 package.json 中也有一个正确的 "typings" 属性,指向由 tsc as explained in the official documentation 生成的现有 .d.ts 文件:

export default function hello(target?: string): void;

但是,我无法通过打字稿代码使用它,无论是打字稿 1.8 还是打字稿 2:

import hello = require('hello-world-emo')

hello()
hello('Offirmo')

tsc 转译或用 ts-node 执行都给出相同的错误信息:

TSError: ⨯ Unable to compile TypeScript
hello.ts (3,1): Cannot invoke an expression whose type lacks a call signature. (2349)

但是,生成的 .js 有效。这似乎是一个打字问题。使用 import hello from 'hello-world-emo' 等其他导入格式也不起作用。

什么是打字稿抱怨?我错过了什么?

如果你想检查tsconfig,模块是here and I'm consuming it from here

问题不在于 typescript,而在于 ES6/CommonJS interop:ES6 和 CommonJS 导出之间没有完美匹配,尤其是对于ES6 "export default",参见。 this article and this open issue on webpack.

这里模块代码是使用ES6模块用ES6写的。构建过程是:

  1. 使用 tsc(typescript 编译器)将 typescript 转译为 ES6
  2. 转译 ES6 代码并将其与 rollup+babel 捆绑用于:
    • ES6@node4 / CommonJS(第一个 class 公民)
    • ES5@node0.10 / CommonJS(仍然广泛使用的遗留)
    • ES5 / umd(用于浏览器)

节点 4(稳定)是第一个 class 公民,相应的包(ES6@node4 / CommonJS)通过 npm "main" 条目公开。它已尽最大努力转换为 CommonJS,使其 可由节点 4 使用,但不再由 typescript 使用 .

另一种选择是使用 tsc 转译为 ES5/CommonJs, 添加特殊注释以将 CommonJS 链接回 ES6 模块 。但随后它 1) 不再捆绑 2) 更粗略地转译(不使用节点 4 中包含的 ES6 功能)和 3) 节点更难使用

折衷方案:通过不使用export default而只使用命名导出来避免 CommonJS / ES6 模块互操作问题。这种缓解技术的唯一缺点是节点 4 :

  • ES6: import hello from '...' 变成 import { hello } from '...' OK
  • node >=6: const hello = require('...') 变为 const { hello } = require('...') OK
  • node <=4: var hello = require('...') 变成 var hello = require('...').hello 不够优雅但可以接受