Reputation: 3611
A former colleague wrote a small chunk of JavaScript (I'm not even sure what to call it. Class? Library?) which I'm now trying to use in a TypeScript portion of our application. We've had some similar situations where we merely added some kind of declaration to a d.ts file. I'm trying to do that now, but I'm getting hung up on the fact that the object I want to use is also a function in the original JS. That is, it is created via the new
operator, yet the constructed object has methods. I'm hoping someone can tell me the best approach for this.
Here is the original JavaScript class/library:
(function (geographies, $) {
geographies.map = function(elementId) {
var self = this;
// Other members elided
// Public Functions
self.findAddress = function (addressDesc, callback){
// elided
}
// Other public methods elided
// Private Methods
function _example() {
// elided
}
// Other private methods elided
}
}(window.geographies = window.geographies || {}, jQuery));
Of course, this results in geographies
being created in the global window namespace, and geographies
has a member, map
which has methods, but is created via new
with a string parameter passed in. Here's an example of geographies.map
being used in existing code (in this context, self
merely refers to a containing component):
if ((self.editAddress.cityId() && self.editAddress.addressLine1())) {
if (map === null) {
map = new geographies.map("addressMapDiv");
}
self.mapVisible(true);
var query = (self.editAddress.addressLine1() ? self.editAddress.addressLine1() : "") +
(self.editAddress.cityDescription() ? " " + self.editAddress.cityDescription() : "") +
(self.editAddress.zipCode() ? " " + self.editAddress.zipCode() : "");
console.log(query);
map.findAddress(query);
}
Now we're starting to use geographies
in TypeScript and thus want some way to get Intellisense and type-checking on it, but there is no plan to reimplement it. We merely want TypeScript to give us a way to use what will be the same object in the window namespace that already exists. I've taken a few cracks at it, but none have seemed to quite make sense. I think the biggest problem is that geographies.map
needs to be newable and accept the string parameter elementId
, while also becoming an object with methods of its own. Here is my latest failed attempt:
interface Map {
constructor(elementId: string): Map;
findAddress(addressDesc: any, callback: any): any;
// Other signatures elided
}
interface GeographiesStatic {
map: Map;
// Other members elided
}
declare var geographies: GeographiesStatic;
Should I be using declare class
? Interfaces? Do I need the declare var
at the bottom, or will that somehow kill the object of the same name that's already in the window namespace? Any guidance would be appreciated.
Upvotes: 1
Views: 124
Reputation: 221014
The code uses the revealing module pattern, which is usually represented with namespace
in TypeScript. An easy declaration for this file would be:
declare namespace geographies {
class map {
constructor(name: string);
findAddress(desc: any, cb: any): any;
}
}
Upvotes: 3