ghybs / Leaflet.TileLayer.Fallback

Replaces missing Tiles by scaled lower zoom Tiles
Apache License 2.0
36 stars 18 forks source link

TypeScript definitions for use in Angular+Ionic project #11

Open Francuchin opened 6 years ago

Francuchin commented 6 years ago

Is there a way to use this in ionic? Try to do it but it shows me this error "Property 'Fallback' does not exist on type 'typeof TileLayer'."

ghybs commented 6 years ago

Hi,

Sounds like your TypeScript complains for lack of type definition. I do not know if there are some typings available yet for this plugin.

If there are not, you can try something in the lines of: https://stackoverflow.com/questions/50528318/how-to-get-leaflet-marker-cluster-freezable-methods-show-up-in-vs-code-intellise/50529126#50529126

Basically, you should look for guides how to use a JS library that lacks typings in a TypeScript project.

Please feel free to share your solution once you have something working, so that others could benefit from your experience! :smiley:

SamiSaves commented 4 years ago

I had this issue with TypeScript as well. I found a post on Stack overflow that described the solution for another leaflet plugin.

I decided to go the easy way and just cast L.tileLayer to any

(L.tileLayer as any).fallback(mapUrl, layerOptions).addTo(map)

Here is the stack oveflow link and copy of the answer:
https://stackoverflow.com/a/13206433

If you don't control the original definition file, and can't make adjustments to it, then unfortunately, what you're trying to do isn't supported currently in TypeScript. An interface in TypeScript is the only construct that allows reasonable extensions as it is only a compile-time/syntax check and not a run-time operation.

You cannot extend a class in TypeScript with new functionality using only TypeScript (and expecting code-completion/Intellisense to work as expected). You could of course add the functions to the prototype for the CircleMarker class, but they would be unavailable to Intellisense and would fail to compile unless you use a type assertion.

Instead of using any, you should be able to use an interface with the type assertion:

declare module L {
export interface CircleMarkerEx {
bindLabel(name: string, options: any): CircleMarker;
}
}

Then:

var cm = <L.CircleMakerEx> circle.bindLabel("name", {});

Thankfully, it doesn't add any run-time overhead, just a bit of extra typing (pun intended!).

There have been suggestions for things like "mix-ins" on CodePlex, but they have not been implemented. Even the mix-in suggestions would not be entirely straightforward to use, and wouldn't work well for libraries that weren't entirely written in TypeScript (as it would be too easy to have JavaScript code that simply could not be safely constructed for example with a mix-in).