This project is read-only.

Using the window object from an AMD module

Topics: General
May 22, 2014 at 11:57 PM
Edited May 22, 2014 at 11:57 PM
I have the need to read and write to the window object from within an AMD module.
interface Window {
    test : string;

window.test = 'test';
This works without AMD, but if the file exports a module:

error TS2094: The property 'MyTest' does not exist on value of type 'Window'.

The only workaround I have found is:
window['test'] = 'test';
However, that eliminates the ability to use the noImplicityAny option, which I would prefer not to lose.

I understand that accessing the global context is not good practice, but there are times when it must be done. Is there a proper way to do this?
May 23, 2014 at 12:04 AM
The right way to do this is to move the interface Window declaration into a separate .d.ts file and /// <reference> that. That will properly extend the global window object.
May 23, 2014 at 1:08 AM
Wow, that would never have occurred to me. Thanks, that does work.

This strikes me as a crazy workaround. Can you describe why this makes sense?
May 23, 2014 at 9:12 AM
It's exactly the same reason that this is an error:
module M {
    interface Window { }
    var x: Window;
Or why this code is fine:
var x = 4;
module N {
    var x = 'foo'; // was number, now string
Any time you're in a child of some scope, declaring an object with some name always introduces a new object rather than merging with the object from the parent scope. Top-level objects in external modules are in a scope that is a child of the global scope, so attempts to merge with objects from the global scope results instead in the creation of a new object.

This is inconvenient in a few cases, but the converse is much much worse -- imagine if every name in lib.d.ts became unusable as the name of an exported object from an internal or external module. The language would be literally unusable.
May 23, 2014 at 6:58 PM
That makes sense, thanks very much for the detailed explanation.