问题
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
orexport
is considered a module. Conversely, a file without any top-levelimport
orexport
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