In a .d.ts
declaration file, I tried to do the same thing in four different ways, but only two of them work:
// Doesn't work.
declare global {
const THREE: typeof import('three')
}
// Doesn't work.
import * as _THREE from 'three'
declare const THREE: typeof _THREE
// Works.
import * as _THREE from 'three'
declare global {
const THREE: typeof _THREE
}
// Works.
declare const THREE: typeof import('three')
The 'three'
module contains export namespace THREE
.
In the first two cases, other .ts
files using THREE
as a global will have the error 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.
With the two cases that do work, other .ts
files using the THREE
global do not have such an error, and they use my definition of THREE
as expected.
f.e., if I use the second non-working option in a .d.ts
file:
// globals.d.ts
import * as _THREE from 'three'
declare const THREE: typeof _THREE
then in another .ts
file:
// other-file.ts
console.log(THREE) // ERROR: 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.
But if I use the fourth (last) option,
// globals.d.ts
declare const THREE: typeof import('three')
then there's no problem in the other file:
// other-file.ts
console.log(THREE) // no problem.
Why do the first two options not work, but the last two do?
Firstly, let me say that given this error: 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.
, you might actually be interested in the new compiler option allowUmdGlobalAccess
in 3.5 PR (although I see you commented on the associated issue, making sure you didn't miss the fix).
Regarding the errors, this is just an intersection of how global augmentation works and what is and isn't a module:
global
can only be used in modules, global
is not necessary in script files import
or export
statement otherwise it is considered a script file.Given these 2 binary rules, we get the exact 4 possibilities you describe
1. Not a module, with global
=> error.
declare global {
const THREE: typeof import('three')
}
Since the file is not a module but a simple script file, using global
is an error, since anything declared in this file would be in the global namespace anyway, so why add global
?
2. Module, without global
=> unused module constant
import * as _THREE from 'three'
declare const THREE: typeof _THREE
Since this file contains an import
it is a module, so the declared const is not in any way in the global scope and thus it's just a module local variable that will go unused. The error you are getting in other files is from the three
module itself (which declares a UMD global namespace)
3. Module, with global
import * as _THREE from 'three'
declare global {
const THREE: typeof _THREE
}
In this case the file is a module, but the definition is in a global
augmentation. This mean that the definition of THREE
will be put in the global namespace and will be available in other files
4. Not a module, no global
declare const THREE: typeof import('three')
In this last case, the file is not a module in spite of the import type. Only import statements make the file a module, import types do not. Since this file is not a module the THREE
constant declared is in the global namespace and available as such in other files.
I also have such kind of issue. Link
With your tsconfig.json you could use:
"compilerOptions": {
"allowUmdGlobalAccess": true,
It gives compiler access to UMD globals, THREE types is listed. So you do not need to import or reference it after. Same like JQuery or $.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With