我有一个关于解决项目中类型的问题。所以基本上我有packageA -> packageB-v1 -> packageC-v1
,并且我想使用packageC-v1
中packageA
中声明的类型。
所有软件包都是由我自己创建的,并且都是打字稿软件包,它们通过在declaration: true
文件中设置tsconfig.json
来生成声明文件,它们各自在{{1 }}文件夹。类型没有相应的*.d.ts
包。
在这种情况下,如何正确导入类型?到目前为止,我已经尝试过:
dist
。此方法有效,但我不喜欢@types/*
需要知道import SomeType from 'packageB-v1/node_modules/packageC-v1/dist/SomeType'
的安装位置,因为它可能会更改,具体取决于软件包管理工具(npm / yarn)或安装顺序(请参阅{{3 }})。我看到的问题是,由于packageA
的版本不同,类型不同并且packageC
对此并不满意。当存在诸如packageC
之类的另一个依赖项时,可能会发生这种情况,其中npm将安装tsc
而不是packageA -> packageB-v1 -> packageBB-v1 -> packageC-v2
下的packageC-v2
。packageC-v1
从packageB/node_modules
导出必要的类型SomeType
,然后从packageA中导出packageB-v1
。这也可行,但是,这还意味着export SomeType from 'packageC-v1'
可以从 all 依赖项中重新导出 all 类型(可能有很多) )其消费者可能可能需要。通常这是不可能的。另外,我听说转口可能会根据情况而产生不同的类型。import SomeType from 'packageB-v1'
的{{1}}文件中,将依赖项显式添加到packageB-v1
中,即使实际上并不直接依赖于此。因此我们可以使用packageA
。不幸的是,这也不起作用,因为我们可能还有另一个依赖链,例如package.json
。在那种情况下,我们应该在packageC-v1
下安装哪个import SomeType from 'packageC-v1/SomeType
版本?这种方法也是不好的,因为即使打字稿实际上不会将packageA -> packageD-v1 -> packageC-v2
生成的JS包中包含packageC
仅用于使用接口,它也可能会为枚举使用。我最后没有尝试的方法是创建自己的packageA
并将其发布(以及其他ts包)。但是,如果我为私人组织编写这些软件包,则意味着我们需要维护一个内部类型存储库,以及维护成对的软件包和与之关联的类型。即使我设法做到了这一点,我仍然可以从版本不匹配,全局声明冲突或名称范围冲突(在packageC
方法中也是如此)中看到这种方法的许多问题。
我不确定这些对您是否有意义,真的需要一些建议。
答案 0 :(得分:1)
让我们从一个简单的例子开始:如果一个软件包A
需要来自软件包C
的东西,那么C
的定义就是A
的直接依赖。
您说您有理由不将C
的依赖项中包含A
我们可能还有另一个依赖链,例如packageA-> packageD-v1-> packageC-v2
在这种情况下,如果A
使用C-v1
中的类型,这应该如何工作?我只能看到两种可能性:
A
时, C
不需要packageD
中的类型。 (顺便说一句,为什么它需要C
类型才能使用packageB
?)
C
类型没有更改,因此C
中的C-v1
类型与C-v2
我对#1和#2唯一看到的解决方案是将C
中的类型拆分为单独的包,例如C-types
,并使其成为{{1}的dev依赖项}。
A
中的类型应该不是是TypeScript生成的C-types
文件,它们应该是所有接口,类型和枚举(但不是类,类是实施细节,并且应保留在d.ts
的{{1}}中,移到单独软件包中包含的常规C
文件中。
对于每个版本的{,您必须以与发布C
相同的方式在npm存储库中发布.ts
,其中包含生成的C-types
和空的C
文件{1}}。我认为没有空的.d.ts
文件不是问题,但是如果是这样,您可以发布手动编写的.js
文件(但是我不知道在发布之前进行类型检查,而没有使用另一个软件包)。无需发布C
到DefinitelyTyped并将它们放到.js
范围内-这只是一个约定,不是必需的。您只需要告诉组织中的每个人都使用.d.ts
而不是C-types
。
您说的是这种方式
就版本而言,我仍然可以看到这种方法的许多问题 不匹配,全局声明冲突或名称范围冲突(这是 在DefinetelyTyped / types方法中也是如此)
首先,强烈建议不要使用全局声明-出于某种原因发明了模块,应该在任何地方显式导入每个地方使用的每个名称。
如果您的@types
使用C-types
中的类型,则使用不同版本的@types/C
的版本问题将完全相同。从A
中分离类型只会让您事先考虑这些问题,而不是希望事情会“正常”。