I've built a lot of APIs and applications using ES2015, but I am not used to the best practices in TypeScript yet, so maybe you can help me. Let's say I am building an API/SDK for a shop. The goal is that the user includes my js file and accesses the shop and its namespaces via the window object, much like it is possible with angular and other libs as well.
window.shop.init();
window.shop.cart.get();
window.shop.cart.set();
window.shop.cart.clear();
In ECMAScript 2015, I would write my methods like get
and set
, import them in my main file and extend the shop object and finally the global object.
// in my cart.js namespace file
export {get} from './get';
// in my shop.js
import * as cart from './cart';
global.shop = {
cart
}
Being a good approach for namespacing in ES2015, it feels kinda wrong in TypeScript having all those module and namespace keywords.
I basically want to achieve the same in TS. I tried things like the following, but with no success.
module shop {
export const cart = {...}
}
(<any>window).shop = shop;
or
namespace shop {
// ...
}
(<any>window).shop = shop;
There where some tutorials claiming that a module is automatically attached to the global/window object, but that did not happen for me.
I am using TypeScript 1.8.10. Any help is greatly appreciated!
There where some tutorials claiming that a module is automatically attached to the global/window object, but that did not happen for me.
Maybe because the code of your namespace
is in an (ES6) module instead of in a script? The differences between scripts and modules are detailed here.
The code below makes a global variable shop
in the browser if it is loaded as a script, ie with a tag <script src="shop.js">
(or you can concatenate this file with other JavaScript files, for example with uglifyjs
).
// File shop.ts
namespace shop {
export const cart = { /* ... */ }
}
If your code is loaded as an ES6 module (ie with the help of Webpack, SystemJS, RequireJS or other), your solution is valid:
(<any>window).shop = shop;
The answer by @paleo is not perfect. It just suppress the type inference for shop.
I also encounter the similar problem this morning. I tried so many "solutions" on SO, but none of them produce no type error absolutely and enable triggering type jumping in IDE(webstorm or vscode).
Finally, from here
https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512
, I find a reasonable solution to attach typings for global variable which acts as interface/class and namespace both.
Example is below:
// typings.d.ts
declare interface Window {
shop?: MyNamespace & typeof MyNamespace
}
declare interface MyNamespace {
somemethod?()
}
declare namespace MyNamespace {
// ...
}
Now, the code above merges the typings of namespace MyNamespace
and interface MyNamespace
into the global variable shop
(the property of window).
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