出现错误:如何从 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'
等其他导入格式也不起作用。
什么是打字稿抱怨?我错过了什么?
问题不在于 typescript,而在于 ES6/CommonJS interop:ES6 和 CommonJS 导出之间没有完美匹配,尤其是对于ES6 "export default",参见。 this article and this open issue on webpack.
这里模块代码是使用ES6模块用ES6写的。构建过程是:
- 使用
tsc
(typescript 编译器)将 typescript 转译为 ES6
- 转译 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
不够优雅但可以接受
我
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'
等其他导入格式也不起作用。
什么是打字稿抱怨?我错过了什么?
问题不在于 typescript,而在于 ES6/CommonJS interop:ES6 和 CommonJS 导出之间没有完美匹配,尤其是对于ES6 "export default",参见。 this article and this open issue on webpack.
这里模块代码是使用ES6模块用ES6写的。构建过程是:
- 使用
tsc
(typescript 编译器)将 typescript 转译为 ES6 - 转译 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
不够优雅但可以接受