How to make an NPM package that uses global types but doesn't augment the project using it?

江枫思渺然 提交于 2020-01-15 07:20:08

问题


The Question:

Any project that reuses a lot of types in many different files can make use of types defined in a script file. Those types are visible globally across the project and don't need to be imported, see the official handbook:

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

I've used these global types in my project and they worked fine. But then I decided to turn the project into a NPM module. The "global" types of that module should only be visible for the module itself.

First I pusblished the module as it was, without adding any <reference/>s and typeRoots. However when imported the module into a different project, TypeScript couldn't find the global types and wouldn't compile.

Then I added <reference path="types.ts" /> to all files in the module that used the global types, then I pushed again. To my surprise, this made the types available not only to the module, but also to the whole project that used it, causing conflicts between local types and the types of the module.

(Note that both versions of the module that I published were perfectly compillable on their own, the problems began when I installed the module using npm i in a different project.)

Is there any way to make the module's "global" types only available in the module?


Structure of my module:

.
├── 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

For the first publish, index.ts and foo.ts contained only regular code – that caused the the types not to get recognized when the project. When I published the module for the second time, I added ///<reference path="types.ts"/> to both index.ts and foo.ts. This got translated into path="types.d.ts" in the compiled files index.d.ts and 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:


If a dependency needs some types, I feel like consumers should get those types, too, so achieving this may not be easy.

You could try defining your global types in a separate library (refer to your previous question for ways to do that; this time the library could be as simple as my-global-library/index.d.ts, unless you need to import typings from sibling dependencies – in which case you may consider spinning those off into a shared library of their own), then installing that library as a devDependency of your NPM package. Any project that consumes your NPM package would then not install the devDependency.



来源:https://stackoverflow.com/questions/55713045/how-to-make-an-npm-package-that-uses-global-types-but-doesnt-augment-the-projec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!