How to declare object literal referencing constructor functions as properties?

Topics: General
Sep 26, 2013 at 5:04 AM
How would I inform the TypeScript compiler about the following JavaScript construct:
var foo = {
   Image: Image
   KeyboardEvent: KeyboardEvent
}
// usage:
var i:number = foo.KeyboardEvent.DOM_KEY_LOCATION_RIGHT;
var e:foo.KeyboardEvent;
e.preventDefault();
This is in a browser environment, so Image and KeyboardEvent refer to the built-in types (declared in lib.d.ts).

Reason: Create a namespace for global types to allow for referencing these types from within a module that hides the global types because of a Type declaration with the same name(s).
Sep 26, 2013 at 4:08 PM
Your code should work as-is since TypeScript will use type inference on foo.

If, however, you need to create an interface for foo (so that you can say var foo: FooInterface) then I think you have to get a bit trickier.
var _ImageVar: typeof Image;
var _KeyboardEventVar: typeof KeyboardEvent;
interface FooInterface {
    Image: typeof _ImageVar;
    KeyboardEvent: typeof _KeyboardEventVar;
}
You can't say Image: typeof Image because your typeof expression will not refer to the global Image class; it'll refer to the Image field within your interface. TypeScript will guess that the type is any. That's why I used _ImageVar and _KeyboardEventVar to create local "aliases" of those two types. This will generate two unused variables in your source code, but a JavaScript minifier can remove them.
Sep 27, 2013 at 7:54 AM
Thx for your response.

This almost works as expected. I can do
declare var foo:FooInterface;
var event = new foo.KeyboardEvent();

event.preventDefault(); // OK
event.xxx(); // Error => OK
event.DOM_KEY_LOCATION_RIGHT; // OK
But there is - understandably - no type being created:
var event:foo.KeyboardEvent; // Error

var event:typeof _KeyboardEventVar = new foo.AlKeyboardEvent(); // Cast Error
It is also important that the solution is type-identical to the original KeyboardEvent class. E.g.
declare function addListener(event:KeyboardEvent); 

addListener(new foo.KeyboardEvent()); // OK - no cast required
In my efforts I was focusing on creating a module declaration that uses declaration merging and export= but to no avail. Do you have any ideas?

What I basically need is to access the global KeyboardEvent type from within a module that defines its own KeyboardEvent type (class).

Thx
Sep 27, 2013 at 7:48 PM
Edited Sep 27, 2013 at 7:49 PM
I think I may have figured it out, although it's a bit messy.

foo.ts:
// foo module, allowing access to KeyboardEvent under a different name.
import __aliases__foo = require('__aliases__foo');
export interface KeyboardEvent extends __aliases__foo.__alias__KeyboardEvent {};
export var KeyboardEvent = __aliases__foo.__alias__KeyboardEvent;
__aliases__foo.ts:
// Intermediary module, used only by the foo module.
export interface __alias__KeyboardEvent extends KeyboardEvent {};
export var __alias__KeyboardEvent = KeyboardEvent;
And now you can use foo.KeyboardEvent just like you'd expect:
import foo = require('foo');
event: KeyboardEvent = new foo.KeyboardEvent();
Does this solve the problem, or did I miss some details again?