【发布时间】:2019-06-27 14:43:24
【问题描述】:
我有一个关于在我的项目中解析类型的问题。所以基本上我有packageA -> packageB-v1 -> packageC-v1,我想在packageA 中使用packageC-v1 中声明的类型。
所有包都是我自己创建的,都是typescript包,通过在tsconfig.json文件中设置declaration: true来生成声明文件,它们各自在dist文件夹中暴露了多个*.d.ts文件。类型没有对应的@types/* 包。
在这种情况下,我应该如何正确导入类型?到目前为止,我已经尝试过:
-
import SomeType from 'packageB-v1/node_modules/packageC-v1/dist/SomeType'。这行得通,但我不喜欢packageA需要知道packageC的安装位置,因为它可能会根据包管理工具(npm/yarn)或安装命令(参见https://medium.com/learnwithrahul/understanding-npm-dependency-resolution-84a24180901b)而改变。我已经看到由于packageC的不同版本,类型不一样,tsc不适合它的问题。当存在像packageA -> packageB-v1 -> packageBB-v1 -> packageC-v2这样的另一个依赖项时,可能会发生这种情况,其中 npm 将在packageB/node_modules下安装packageC-v2而不是packageC-v1。 - 首先通过
export SomeType from 'packageC-v1'从packageB-v1导出必要的类型SomeType,然后从packageA我可以import SomeType from 'packageB-v1'。这也有效,然而,这也意味着packageB-v1可以从 all 的依赖项(可能有很多)重新导出 all 类型其消费者可能需要。这通常是不可能的。另外,我听说再导出可能会产生不同的类型,具体取决于每种情况。 - 在
packageA的package.json文件中,显式添加对packageC-v1的依赖,即使它实际上并不直接依赖它。所以我们可以使用import SomeType from 'packageC-v1/SomeType。不幸的是,这也不起作用,因为我们可能有另一个依赖链,例如packageA -> packageD-v1 -> packageC-v2。在这种情况下,我们应该在packageA下安装哪个packageC版本?这种方法也很糟糕,因为即使 typescript 实际上不会在从packageA生成的 JS 包中包含packageC以仅使用接口,它也可能对枚举执行此操作。
我没有尝试的最后一种方法是创建我自己的@types/packageC-v1 并发布它(以及我的其他 ts 包)。但是,如果我为私有组织编写这些包,这意味着我们需要维护一个内部类型存储库,以及维护与它们关联的包和类型的配对版本。即使我设法做到了,我仍然可以看到这种方法在版本不匹配、全局声明冲突或名称范围冲突方面存在许多问题(DefinetelyTyped/types 方法中也是如此)。
我不确定这些对你是否有意义,在这里真的需要一些建议。
【问题讨论】:
-
我什至开始认为,typescript 通过创建与 JS 包分开的类型声明文件的方法可能是错误的...... Javascript 应该以某些方式(例如,注释)原生支持类型。我开始明白为什么人们仍然可以使用 JSDoc 而不是 TS。
-
我认为除了@artem 在下面发布的内容之外,真的没有什么好的解决方案。否则,消费者需要直接依赖包。那是因为 typescript 中的枚举会被转译成 JS 代码,如果消费者想使用它,使用源代码是没有区别的。对于接口,我们也许可以重新导出它,但我们也应该询问消费者为什么要使用库依赖中的接口。通常会有更简单的方法不使用它们,而是使用我们库中的 API
标签: typescript npm dependencies yarnpkg