Pau*_*rts 9 publishing npm typescript
将 TypeScript 包发布到 npm 以提供接受来自一个或另一个对等依赖项的输入的函数时,如何定义可选的对等依赖项?
import { ExternalFoo } from 'foo';
import { ExternalBar } from 'bar';
export const customPackage = (source: ExternalFoo | ExternalBar) => {
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
当缺少两个选项之一时,如何防止使用我的包的人出错?
从 Typescript 3.8 开始,您可以使用以下语法:
import type { ExternalFoo } from "foo";
Run Code Online (Sandbox Code Playgroud)
因此,如果您只是将该库用于类型信息,您可能不必将其列为 adependency或其他optionalDependency。您可能更愿意将其保留为 a,peerDependency以便如果您的用户具有这些依赖项,他们将使用与您的库兼容的版本。当然,添加 asdevDependency也很有用。
导入将d.ts仅存在于生成的文件中,而不存在于.js转译的代码中。但是,一个问题是,如果用户没有安装该库,则该类型会变成这样any,这可能会使您自己的打字变得混乱。例如,如果foo未安装,您的功能将变为
customPackage = (source: any | ExternalBar) =>
// equivalent to customPackage = (source: any) =>
Run Code Online (Sandbox Code Playgroud)
对于这个特定的类型注释,它很糟糕,因为即使我已经bar安装,它也不会用于该类型检查。因此,有是一个办法不依赖于该库了,但它并没有解决的困难写作类型注释,不会打破,如果该类型是不存在的。
结合当前所有答案,这是我为当前版本的 TypeScript(截至 2021 年末)找到的最佳解决方案:
// @ts-ignore -- optional interface, will gracefully degrade to `any` if `foo` isn't installed
import type { Foo } from "foo";
import type { Bar } from "bar";
// Equates to `Bar` when `foo` isn't installed, `Foo | Bar` when it is
type Argument = any extends Foo ? Bar : (Foo | Bar);
export function customPackage(source: Argument): void {
...
}
Run Code Online (Sandbox Code Playgroud)
你可以自己尝试一下。如果foo安装了,导出的方法将接受Foo或Bar参数,如果没有安装,则仅接受Bar(not any)。
你的情况是目前TypeScript支持不好的情况。
先总结一下你的情况:
foo是bar您的可选依赖项,这意味着您希望您的消费者将其中之一与您的库一起使用。dependencies您的package.jsoncustomPackage功能是公开的。由于第 3 点,您需要在库类型中包含该类型,这意味着您需要添加foo和bar作为依赖项。这与第1点和第2点相矛盾。
foo如果和的类型bar来自DefinitelyTyped(即来自包@types/fooand @types/bar),那么您可以将它们添加为您的dependenciesin package.json。这样问题就解决了。
如果foo和的类型bar与库本身一起分发,您必须将库包含为dependencies(您不想要的),或者创建类型ExternalFoo和ExternalBar您自己的副本。
这意味着您将不再依赖foo和bar。
另一种方法是仔细查看您的库,看看将foo和bar作为依赖项包含在内是否有任何危害。根据您的图书馆的性质,它可能没有您想象的那么糟糕。
就我个人而言,我通常会自己声明类型。JavaScript 首先是一种动态语言。
| 归档时间: |
|
| 查看次数: |
5181 次 |
| 最近记录: |