Define global namespace/variable within a TypeScript module
Solution 1
The solution is to declare namespace in global.
declare global {
namespace foo.blah {
function baz() {
console.log('hello');
}
}
}
Solution 2
When you add the import
, you switch from internal modules to external ones, as the spec says:
In external modules, relationships between files are specified in terms of imports and exports at the file level. In TypeScript, any file containing a top-level import or export is considered an external module.
http://www.typescriptlang.org/Handbook#modules-going-external
The philosophy behind external modules is to avoid global objects, why don't you create a new module with foo.blah
(and all the stuff you need) and import it as TypeScript expects it?
Jesse
Updated on June 17, 2022Comments
-
Jesse about 2 years
In TypeScript I can define a global/top-level namespace and use it in another file like so:
namespace foo.blah { export function baz() { console.log('hello'); } }
And in another file, this works:
foo.blah.baz();
However, if I then import something from another module:
import Thing from 'boo'; namespace foo.blah { export function baz() { console.log('hello'); } }
Suddenly my whole file is a module, the
foo.blah
namespace is local, not global, and thefoo.blah.baz()
call in the other file fails.export namespace ...
just causes the namespace to become part of the module's export, not a global.Is there a way to write a TypeScript file which imports from other modules but also defines global/top-level symbols?
At the moment I'm doing this:
import Thing from 'boo'; import * as $ from 'jquery'; namespace foo.blah { export function baz() { console.log('hello'); } } $.extend(true, window, {foo});
Which works, but the TypeScript compiler still can't see that
foo.blah...
exists as a global in other files.(The file is the entry point for Webpack, and I'm trying to import things from other modules in the Webpack bundle and assign them to globals so they can be used in
<script>
tags on the page.) -
Jesse over 8 yearsAs I said, I'm trying to define global variables for use in
<script>
tags inside the page, using what is exported by other modules. (The application is over a decade old and I'm trying to incrementally move it to pure TypeScript.) -
MartyIX over 8 yearsIf you want to slowly migrate then why don't you use
.d.ts
files (e.g. github.com/DefinitelyTyped/DefinitelyTyped/blob/master/ace/…) and then just use references like this///<reference path="relative/path/to/file.d.ts" />
? -
Parzh from Ukraine about 2 yearsThis yields compiler error
An implementation cannot be declared in ambient contexts.
. Thedeclare
keyword designates an ambient context, which means that the given entity does not exist in runtime, only in TypeScript.