1

I have a Leaflet map that contains some GeoJSON layers (and other layers besides). I want to iterate over the layers to find the GeoJSON layer with a property matching some target value. The problem I have is getting the type annotations right, such that I don't get warnings from the TypeScript compiler.

The core issue is:

const map:L.map = ...

map?.eachLayer(layer => {
  // @ts-expect-error GeoJSON layers do have a feature property
  const feature = layer.feature

  if (feature) {
    const layerId = feature.properties['someIdProperty']

      if (layerId === targetId) {
        // @ts-expect-error We know that this layer has bounds
        map?.fitBounds(layer.getBounds())
      }
    }
  })

The code does run correctly, but I can't find a way to type the layer variable to avoid getting compiler warnings. Hence resorting to the ugly @ts-expect-error hack.

2 Answers 2

1

You can check if the instance of the layer is a GeoJSON layer:

map?.eachLayer(layer => {
    //GeoJSON layers do have a feature property
    if(layer instanceof L.GeoJSON){
        const feature = layer.feature
        if (feature) {
            const layerId = feature.properties['someIdProperty']
            if (layerId === targetId) {
                map?.fitBounds(layer.getBounds())
            }
        }
    }
})
2
  • Thanks, that does help. I'm still getting a compiler warning from feature.properties though Commented Jun 1, 2022 at 10:42
  • Actually, I have to update that comment. This solution makes the type-checker happy (well, happier), but the actual if-condition is failing. Looking at the app in devtools, the layer is actually an instance of NewClass, which I assume is some dynamically generated class that the Leaflet loader creates. Commented Jun 1, 2022 at 11:00
0

One-liner improvement on @Falke Design's answer, also looking for layers which are not a collection (for when you are updating popup contents) :

map?.eachLayer((layer) => 
  (layer instanceof L.GeoJSON)
  && layer.feature?.type !== 'GeometryCollection'
  && layer.feature?.type !== 'FeatureCollection'

  ? layer.feature?.properties?.popupContent
  : 'No popup content')
3
  • One-lining something like that isn't an improvement
    – Sean
    Commented Jun 28 at 14:36
  • @Sean I posted it as an answer rather than a comment to make it readable. The improvement consists in the fact that it verifies the layer's feature type.
    – altius_rup
    Commented Jun 30 at 10:02
  • Suggest editing your answer to add that explanation and un-one-lining it so that's more evident
    – Sean
    Commented Jun 30 at 16:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.