Esri/esri-leaflet-vector

Property 'Vector' does not exist on type 'typeof esri'

julianklose opened this issue · 10 comments

Describe the bug

I'm trying to import esri-leaflet and esri-leaflet-vector as ES modules in typescript. Since using L.esri is not working I applied the workaround.

import * as esri from "esri-leaflet";
import "esri-leaflet-vector";

esri.Vector.vectorBasemapLayer("OSM:Standard", { apiKey: "" }).addTo(this.map);

This gives the error: Property 'Vector' does not exist on type 'typeof esri'.
Is there a workaround for esri-leaflet-vector? There are typings for esri-leaflet-vector but no documentation or examples on how to use it.

Reproduction

No jsbin etc for typing problems...

Logs

No response

System Info

Leaflet version: `v1.9.2`
Esri Leaflet version: `v3.0.9`
Esri Leaflet Vector version: `v4.0.0`
Typescript version: `v4.2.4`

Additional Information

No response

Try to import like this:

import { Map as LeafletMap } from "leaflet";
import { vectorBasemapLayer } from "esri-leaflet-vector";

then:

vectorBasemapLayer("ArcGIS:Streets", {
  apiKey: '...'
}).addTo(map);

I just realized that the npm packages don't include the type declaration file (index.d.ts). Without it, the library cannot be used with typescript.

@julianklose we should provide types for this but in the meantime you can declare the type of this as any:

// global.d.ts
declare module "esri-leaflet-vector";

Hey @patrickarlt, when are you guys planning to provide types to be able to use it in Angular?

I created a type declaration, but it is not complete:

declare module "esri-leaflet-vector" {
  type VectorBasemaps =
    // Streets and navigation
    | "ArcGIS:DarkGray"
    | "ArcGIS:DarkGray:Base"
    | "ArcGIS:DarkGray:Labels"
    | "ArcGIS:LightGray"
    | "ArcGIS:LightGray:Base"
    | "ArcGIS:LightGray:Labels"
    | "ArcGIS:Navigation"
    | "ArcGIS:NavigationNight"
    | "ArcGIS:Streets"
    | "ArcGIS:StreetsRelief"
    | "ArcGIS:StreetsRelief:Base"
    | "ArcGIS:StreetsNight"
    // Imagery and topography
    | "ArcGIS:Imagery"
    | "ArcGIS:Imagery:Standard"
    | "ArcGIS:Imagery:Labels"
    | "ArcGIS:Topographic"
    | "ArcGIS:Topographic:Base"
    | "ArcGIS:Terrain"
    | "ArcGIS:Terrain:Base"
    | "ArcGIS:Terrain:Detail"
    | "ArcGIS:Oceans"
    | "ArcGIS:Oceans:Base"
    | "ArcGIS:Oceans:Labels"
    | "ArcGIS:Hillshade:Dark"
    | "ArcGIS:Hillshade:Light"
    // OpenStreetMap
    | "OSM:Standard"
    | "OSM:StandardRelief"
    | "OSM:StandardRelief:Base"
    | "OSM:DarkGray"
    | "OSM:DarkGray:Base"
    | "OSM:DarkGray:Labels"
    | "OSM:LightGray"
    | "OSM:LightGray:Base"
    | "OSM:LightGray:Labels"
    | "OSM:Streets"
    | "OSM:StreetsRelief"
    | "OSM:StreetsRelief:Base"
    // Creative
    | "ArcGIS:HumanGeography"
    | "ArcGIS:HumanGeography:Base"
    | "ArcGIS:HumanGeography:Detail"
    | "ArcGIS:HumanGeography:Label"
    | "ArcGIS:HumanGeographyDark"
    | "ArcGIS:HumanGeographyDark:Base"
    | "ArcGIS:HumanGeographyDark:Detail"
    | "ArcGIS:HumanGeographyDark:Label"
    | "ArcGIS:ColoredPencil"
    | "ArcGIS:Community"
    | "ArcGIS:Nova"
    | "ArcGIS:ChartedTerritory"
    | "ArcGIS:ChartedTerritory:Base"
    | "ArcGIS:Midcentury"
    | "ArcGIS:Newspaper"
    | "ArcGIS:ModernAntique"
    | "ArcGIS:ModernAntique:Base";

  interface BasemapLayerOptions extends L.TileLayerOptions {
    apiKey?: string;
    token?: string;
  }

  class VectorBasemapLayer extends L.TileLayer {
    constructor(key: VectorBasemaps, options?: BasemapLayerOptions);
  }

  export function vectorBasemapLayer(key: VectorBasemaps, options: BasemapLayerOptions): VectorBasemapLayer;

  export function vectorTileLayer(key: any, options: any): any;
  export const VectorTileLayer: any;
  export function maplibreGLJSLayer(options: any): any;
  export const MaplibreGLJSLayer: any;
}

Alternatively would it work for your case to put // @ts-expect-error on the line above where the TS error is occurring to suppress it temporarily? Then in the future whenever types are available that work in your environment it will show an error when that line is no longer necessary to include.

I'm not entirely sure when I'll have enough time to provide full types for this project. The types from @julianklose look like a good start but I would like to see a few less anys and also expose the full MapLibre types since MapLibre is not written in Typescript.

I would be more then happy to accept a PR on this though. 😄

This project does have a basic types file:
https://github.com/Esri/esri-leaflet-vector/blob/master/index.d.ts

It is very basic - PRs are welcome to help extend it.

I think there may be an issue with our release process that index.d.ts is not getting included in the NPM package:
https://unpkg.com/browse/esri-leaflet-vector@4.0.1/

I think that may be the core issue here.

Replication case: open this project in VS Code, https://github.com/gavinr/esri-leaflet-react-demo/ and remove this file: https://github.com/gavinr/esri-leaflet-react-demo/blob/master/src/types.d.ts

It looks like the existing index.d.ts files isn't getting included in the published package becasue it isn't in the files array in the package.json. Once it is added there the types should show up.

Then we can accept PRs to improve the types.

The index.d.ts is now included in the NPM release starting at v4.0.2 (see https://unpkg.com/browse/esri-leaflet-vector@4.0.1/ vs https://unpkg.com/browse/esri-leaflet-vector@4.0.2/)

I've tested this myself in https://github.com/gavinr/esri-leaflet-react-demo/ and it seems to fix the Typescript errors.

As mentioned in previous messages, the current index.d.ts is very basic. We welcome PRs to improve this types file. Thank you!