如何制作使用全局类型但不使用全局类型扩展项目的NPM软件包?

时间:2019-04-16 16:46:49

标签: typescript npm npm-publish

问题:

任何在许多不同文件中重用许多类型的项目都可以使用脚本文件中定义的类型。这些类型在整个项目中全局可见,不需要导入,请参见the official handbook

  

在TypeScript中,就像在ECMAScript 2015中一样,任何包含顶级importexport的文件都被视为一个模块。相反,没有任何顶级importexport声明的文件将被视为脚本,其内容在全局范围内可用(因此也适用于模块)。

我在项目中使用了这些全局类型,并且它们运行良好。但是后来我决定将项目变成NPM模块。该模块的“全局”类型仅对模块本身可见。

首先,我按原样按原样使用该模块,而不添加任何<reference/>typeRoots。但是,将模块导入另一个项目时,TypeScript无法找到全局类型,也无法编译。

然后,我将<reference path="types.ts" />添加到使用全局类型的模块中的所有文件中,然后再次推送。令我惊讶的是,这不仅使模块可以使用类型,而且对使用该模块的整个项目也可用,从而导致本地类型与模块类型之间发生冲突。

(请注意,我发布的模块的两个版本均可完全自行编译,当我在另一个项目中使用npm i安装模块时,问题就开始了。)

有什么方法可以使模块的“全局”类型仅在模块中可用?


我的模块的结构:

.
├── dist
│   ├── index.d.ts
│   ├── index.js
│   ├── foo.d.ts
│   ├── foo.js
│   ├── types.d.ts
│   └── types.js
├── package.json
├── src
│   ├── index.ts  ← contains import/export
│   ├── foo.ts    ← contains import/export
│   └── types.ts  ← contains only types, no import/export
└── tsconfig.json

对于第一次发布,index.tsfoo.ts仅包含常规代码-这导致类型在项目时无法识别。当我第二次发布该模块时,我在///<reference path="types.ts"/>index.ts中都添加了foo.ts。在编译文件path="types.d.ts"index.d.ts中将其转换为foo.d.ts

package.json:

{
  "name": "@foo/foo",
  "version": "1.0.0",
  "main": "dist/index.js"
}

tsconfig.json:

{
  "include": ["./src"],
  "compilerOptions": {
    "moduleResolution": "classic",
    "outDir": "./dist",
    "module": "commonjs",
    "declaration": true
  }
}

1 个答案:

答案 0 :(得分:1)

如果依赖项需要某些类型,我觉得消费者也应该获得这些类型,因此实现此目标可能并不容易。

您可以尝试在单独的库中定义全局类型(有关方法,请参见previous question;这一次,该库可以像my-global-library/index.d.ts一样简单,除非您需要导入类型(从同级依赖项中删除)–在这种情况下,您可以考虑将它们拆分成自己的共享库),然后将该库作为NPM软件包的devDependency安装。这样,使用NPM软件包的所有项目都不会安装devDependency