Doug Doug - 21 days ago 6
TypeScript Question

MarkerCluster LeafletJS plugin TypeScript definition file creation

I am using LeafletJS to map out floor plans. I recently learned a little about TypeScript at DevIntersection and wanted to start converting all of my JS to use it. Luckily someone already created the definition file for Leaflet, but one of the plugins I use doesn't have one (MarkerCluster).

I have the plugin to the point where it compiles (after some small additions to the leaflet definition file) but when I try to use it I don't see any of its methods (see usage example below). I also tried creating a definition file from it but what it created was empty (using tsc --declaration). Since the definition file for Leaflet and the plugin are a bit long I uploaded them:

leaflet.d.ts , leaflet.markercluster.ts

Usage:

/// <reference path="typings/jquery/jquery.d.ts" />
/// <reference path="typings/jqueryui/jqueryui.d.ts" />
/// <reference path="typings/leaflet/leaflet.d.ts" />
/// <reference path="typings/leaflet.markercluster.ts" />

module FloorPlans
{
export class Floor
{
deskMarkers : L.MarkerClusterGroup; // <-- Compile error
peopleMarkers: L.MarkerClusterGroup; // <-- Compile error
tileLayer: L.TileLayer;
desks = new Object();
people = new Object();

constructor(public floorName: string, public floorID: number) { }

}
}


Error:


The property 'MarkerClusterGroup' does not exist on value of type 'L'


Any ideas or guidance on where to go from here?

Answer

There are a lot of different conventions for creating "classes" in JavaScript, and TypeScript doesn't know anything about any of them. What you have in leaflet.markercluster.ts is legal JavaScript and therefore legal TypeScript, but it's not broken into classes as TypeScript understands them and that's why the declaration file generated for it is empty.

Except in rare cases declaration files are created by hand, and that's probably what you're going to have to do here. It will probably start off something like this:

/// <reference path="leaflet.d.ts" />
declare module L {
    export class MarkerClusterGroup extends FeatureGroup {
        initialize(options: any): void;
        addLayer(layer:ILayer):MarkerClusterGroup;
        addLayer(layer:LayerGroup):MarkerClusterGroup;
        // and so on and so forth
    }
}

I've had to create a couple declaration files myself and after a short learning curve it's not too hard. I found this blog post to be super helpful for getting started (props to Steve if you're reading this) and then learning by example on definitelytyped.

Once you're happy with your declaration file remember to contribute back to definitelytyped for warm fuzzy feelings.