Reputation: 10587
I have a JavaScript project, which can be reduced to this:
console.log(depA());
console.log(depB());
I am pulling in the dependencies by using the plain old script
tag:
<html>
<head>
<script src="pkg/depA/index.js"></script>
<script src="pkg/depB/index.js"></script>
<script src="src/index.js"></script>
</head>
</html>
The packages I am using are JavaScript packages, both are like this:
function depX() { // Where X is A or B
return 'depX';
}
Both of these packages have their own index.d.ts typings alongside their
index.js`.
For package A this is straightforward:
declare function depA(): string;
For package B, which can also be used as a module, the typings are also a module file:
declare function depB(): string;
export default depB;
Like I said, this is a JavaScript project and I am using TypeScript for type checking:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"types": [
"../pkg/depA",
"../pkg/depB",
]
}
}
I a referencing the package typings using compilerOptions.types
, because this being a plain JavaScript project, I am not using NPM or anything to install the packages or the typings, and since this is JavaScript code, there are no import
statements or requires
(I am not using ESM and there is no build process for CJS), so TypeScript cannot be aware of the packages and know to pull in their types in any other way but being told explicitly using compilerOptions.types
.
The problem is, typings for the package B communicate it is a module file, so the depB
function is declared on the module scope, not the window scope. depA
and depB
are only demonstrations, there are real world packages with which I am facing this, so I have no option of removing the export default
and making the typings a non-module file, but I can create a pull request and add support for making the typings file both a window-global function and a module other consumers whole use modules can import.
My question then is, how can depB
typings be amended so they remain a module file (and no existing consumers are broken), but they also communicate the depB
function exists on the window scope, so TypeScript knows it's okay to just call it in-place, standalone, no import, no nothing?
At runtime, that is the case, so the typings are the problem, they just don't communicate this for TypeScript to know (I think), so I ask, how can they be changed to do so?
I've made a GitHub repository which demonstrates the problem, there is an associated public Azure Pipeline which runs the TypeScript type check which shows depA
is accessible with no problem, but depB
is invisible at window
as it is communicated as only being a module.
Upvotes: 0
Views: 754
Reputation: 25790
The pattern you are describing is often used to define UMD packages. Their contents can be imported or — if there is no module bundler — accessed from the global scope.
TypeScript handbook explains what their definitions should look like. Your case is defined in the module-function.d.ts
template, which can be reduced to:
depB.d.ts
declare function depB(): string;
export as namespace depB;
export = depB;
Including the above in your project did the job for me, and no upstream changes were required.
See the pull request.
Upvotes: 1