mapbox-gl-leaflet in react-leaflet with TypeScript?

2.2k views Asked by At

I am trying to get this implementation described at Render mapbox vector tiles inside react-leaflet? working, except I'm using TypeScript.

So my file looks like this:

import * as L from "leaflet";
import {} from "mapbox-gl-leaflet";
import * as PropTypes from "prop-types";
import { GridLayer, withLeaflet } from "react-leaflet";

class MapBoxGLLayer extends GridLayer {
  createLeafletElement(props) {
    return L.mapboxGL(props);
  }
}

/*
* Props are the options supported by Mapbox Map object
* Find options here:https://www.mapbox.com/mapbox-gl-js/api/#new-mapboxgl-map-options-
*/
MapBoxGLLayer.propTypes = {
  accessToken: PropTypes.string.isRequired,
  style: PropTypes.string
};

MapBoxGLLayer.defaultProps = {
  style: "mapbox://styles/mapbox/streets-v9"
};

export default withLeaflet(MapBoxGLLayer);

However I get the following error:

Property 'mapboxGL' does not exist on type 'typeof import("c:/Users/.../node_modules/@types/leaflet/index")'.ts(2339)

So leaflet doesn't have a definition for mapboxGL (which makes sense as mapboxGL is not a part of it) - but how do I create or reference a definition for mapboxGL that allows me to call L.mapboxGL(props) ?

1

There are 1 answers

3
Vadim Gremyachev On BEST ANSWER

To resolve this error type definitions for mapbox-gl-leaflet needs to be installed, for example:

npm install --save @types/mapbox-gl-leaflet

And last but no least, react-leaflet type definitions are not fully compatible with react-leaflet v2 at the moment and some extra adjustment is required. Since the current version of @types/react-leaflet is targeting react-leaflet v1, some type definitions from version 2 are missing (refer this thread for a more details), for example withLeaflet HOC. The good news is a PR which adds support for version 2 has been already submitted (but not yet approved)

Anyway the missing withLeaflet type def could be declared like this:

declare module "react-leaflet" {
  const withLeaflet: <T>(component: T) => T;
}

and finally the component could be implemented like this:

import * as L from "leaflet";
import "mapbox-gl-leaflet";

declare module "react-leaflet" {
  const withLeaflet: <T>(component: T) => T;
}


import {Children, MapLayer, withLeaflet} from "react-leaflet";


export interface IMapboxGLProps extends L.MapboxGLOptions {
  children?: Children;
}


class MapBoxGLLayer extends MapLayer<IMapboxGLProps,{}> {

  public static defaultProps = {
    style: "mapbox://styles/mapbox/streets-v9"
  };

  public createLeafletElement(props:IMapboxGLProps)  {
    return L.mapboxGL(props);
  }

  public render() {
    return null
  }
}

export default withLeaflet(MapBoxGLLayer);

Here is a demo