【问题标题】:Why does tsc give so cryptic errors when leaking transitive implementation types?为什么 tsc 在泄漏传递实现类型时会给出如此神秘的错误?
【发布时间】:2017-01-01 01:31:18
【问题描述】:

我有一个节点模块 A 依赖于另一个节点模块 B,两者都是用 Typescript 编写的。模块 B 将 Promise 返回给 A,并选择 bluebird 作为 Promise 实现。 B 当然有蓝鸟的打字。

但是,如果 A 没有蓝鸟类型(在我的情况下可能不应该),我会收到如下错误:

~/d/p/ensime-vscode ❯❯❯ tsc -p .                                                                                                                                                              ⏎ master ✭ ✱
node_modules/ensime-client/**/file-utils.d.ts(1,26):
 error TS2307: Cannot find module 'bluebird'.

我花了一段时间才意识到这是由于我泄露了 Bluebird 的具体 Promise 类型。将所有公共返回类型更改为 PromiseLike 会使错误消失。

我的问题是,有没有办法在我的独立模块 B 上更早地检测到这些?我记得当模块泄漏以前不公开的类型时有时会出错,但在这种情况下,模块 B 构建得很好。这对我来说非常模糊,因为我对 Typescript 很陌生。我猜 Typescript 与我习惯的不同。

另外,tsc 是否有可能针对这些情况发出更好的错误消息?

小更新: 当我“泄漏”本地定义的类型时,它会直接在 B 中捕获:

export interface CompletionsResponse extends Typehinted {
  completions: [Completion]
}

interface Completion {
}

[ts] 导出接口的属性“完成”具有或正在使用私有名称“完成”。 接口完成

如果我要从诸如“bluebird”之类的依赖项中暴露某些东西,我希望能够直接捕捉到这种东西。Promise 也是如此。我从来没有打算将'bluebird'作为传递依赖项公开,老实说,我什至不知道如何使用打字来做到这一点?因此,当它构建得很好时,发生的事情是“bluebird”默默地变成了 npm toungue 中的一种“对等依赖”。

【问题讨论】:

  • 泄漏类型到底是什么意思?
  • 就是我在全文中描述的内容。我正在从 bluebird 泄漏 Promise,并从一个没有 bluebird.Promise 类型的依赖者那里得到这些错误。在泄漏我的意思是,这不是故意的 - 我应该从一开始就将公共 API:s 输入到 PromiseLike/Thenable,但我认为我需要一种更好的方法来捕捉这些 tsc 在依赖者上编译错误。跨度>
  • 如果我理解错了,请纠正我:你有一个模块 A,它依赖于模块 B,通过模块 B Promise 类型得到。例如。因为 B 声明文件指定 B.awesomeFunction() 返回一个 (Bluebird) Promise?如果是这样,您是否确保模块 B 正确处理其类型依赖关系?
  • 这基本上就是我要问的问题 - 我如何确保 B “正确处理其类型依赖关系”? B 构建良好,但公开了不可传递的类型。

标签: node.js typescript typescript-typings


【解决方案1】:

如果一个包对另一个模块有类型依赖,这个依赖应该包含在包的typings.json中,typings install bluebird --save

模块 B 的类型声明应该类似于 type declaration for redux-persist(但在实际项目中)。它depends on redux for several types。因此,有一个dependency listed in the typings.json

关于打字稿错误消息,它们有点痛苦。 ¯\_(ツ)_/¯

【讨论】:

  • 哦,好吧,那我想我做错了什么。我没有单独发布我的模块 B 的类型,而是与该模块一起发布。模块 B 在其 typings.json 中列出了 bluebird,但模块 A 甚至没有 typings.json。这是一个 vscode 扩展…
  • 另外,我实际上并不希望将 bluebird 的类型暴露给模块 A,所以我认为这不是我问题的答案。您的示例在这里看起来就像我的模块“B”:github.com/ensime/ensime-node/blob/master/typings.json#L4
  • 另外,在模块“A”中进行分型安装也无济于事。同样的问题。
  • 我完全错过了球,我写的似乎没有多大意义。我安装了你的包,但我不能让它使用正确的文件声明。这可能与您的 gulp 配置有关,而不是使用外部声明文件。
  • 如果我有时间,我可能会在 github 上设置一个超级最小的 repro case 并重新迭代这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多