Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define the type of a custom leaflet control

When looking through the type definitions from @types/leaflet you can see custom controls defined similar to:

export namespace Control {
    ...
    class Zoom extends Control {
        constructor(options?: ZoomOptions);
        options: ZoomOptions;
    }
    ...
}

However, when creating your custom control through:

declare module 'leaflet' {
    namespace Control {
        class CustomControl extends Control {
            constructor(options: CustomOptions);
        }
    }
    namespace control {
        function customControl(options: CustomOptions): Control.CustomControl;
    }
}

L.Control.CustomControl = L.Control.extend({
    ...
});

throws a typescript error: Type '(new (...args: any[]) => any) & typeof Class' is missing the following properties from type 'typeof CustomControl': Zoom, Attribution, Layers, Scale, and 6 more.

This seems to happen because the namespace and class Control go through Typescript's Declaration Merging. This causes CustomControl to require properties from the namespace rather than just the class.

Is there a way to fix this or circumvent it without forcing type any?

like image 206
Bohr Hew Avatar asked Jun 17 '19 22:06

Bohr Hew


1 Answers

We need to add more typings for method "extend".

Insert this code before your control declaration

declare module 'leaflet' {
  namespace Control {
    function extend(props: any): {new(...args: any[]): any} & typeof Control;
  }
}

With members

declare module 'leaflet' {
  namespace Control {

    function extend<T extends Object>(props: T): {new(...args: any[]): T} & typeof Control;
  }
}

You can add same declaration for Handler

like image 184
Nail Achmedzhanov Avatar answered Nov 18 '22 02:11

Nail Achmedzhanov