Extending Interfaces of Existing Typescript Definitions

Randy Bacon Typescript

I honestly have a love/hate relationship with Typescript. Most of the time I enjoy the shortcuts created by using Typescript. Typescript has several positive features that help me code faster and smarter, such as quick access to model or class properties, the ability to jump to code using F12, auto-complete on third-party and local libraries, and the layout of the resulting code structure. However, there are several things that I struggle with using Typescript, the biggest one is using a method on an object that isn't in the Typescript definition file or a property you have added to a custom object.

Extending Leaflet Definitions

I have run into this several times using Angular and the Leaflet Angular directive. The Leaflet Angular directive uses some models that are derivatives of the real underlying Angular models. The marker model is one of these items. Recently on a project I was working on, I could not get the following code to compile in Typescript.

marker.focus = true;

This is because I had declared this marker as the type L.Marker so I could access the methods that are shared by the Leaflet Angular directive object. Of course this definition does not contain the focus method which is specific to the Leaflet Angular object. I really didn't want to recreate definitions for this object. To account for this, I created the following interface to extend the Typescript definition.

declare module L {
    interface AngularMarker extends Marker {
        focus: boolean;
    }
}

Then in the resulting code, the marker can be cast to our new type and Typescript will allow us to compile.

(marker).focus = true

Closing Thoughts

I hope this helps someone save some time in the future. I was stuck on this one for about an hour near the end of a sprint and it was frustrating. Until next time - happy coding!