mapbox-gl-draw icon indicating copy to clipboard operation
mapbox-gl-draw copied to clipboard

Argument of type 'MapboxDraw' is not assignable to parameter of type 'IControl'

Open alamenai opened this issue 1 year ago • 12 comments

@mapbox/mapbox-gl-draw: ^1.4.3, @mapbox/mapbox-gl-draw-static-mode: ^1.0.1, mapbox-gl: ^3.2.0,

Steps to Trigger Behavior

Code



    modes.static = StaticMode

    const draw = new MapboxDraw({
      displayControlsDefault: false,
      touchEnabled: true,
      modes,
      styles: [
        // ACTIVE (being drawn)
        // line stroke
        {
          id: "gl-draw-line",
          type: "line",
          filter: ["all", ["==", "$type", "LineString"], ["!=", "mode", "static"]],
          layout: {
            "line-cap": "round",
            "line-join": "round",
          },
          paint: {
            "line-color": "#84cc16",
            "line-width": 2, // Line width
            "line-opacity": 1, // Fully opaque lines
          },
        },
        // polygon fill
        {
          id: "gl-draw-polygon-fill",
          type: "fill",
          filter: ["all", ["==", "$type", "Polygon"], ["!=", "mode", "static"]],
          paint: {
            "fill-color": "#84cc16",
            "fill-outline-color": "#84cc16",
            "fill-opacity": 0.1, // Semi-opaque fill
          },
        },
        // polygon outline stroke
        // This doesn't style the first edge of the polygon, which uses the line stroke styling instead
        {
          id: "gl-draw-polygon-stroke-active",
          type: "line",
          filter: ["all", ["==", "$type", "Polygon"], ["!=", "mode", "static"]],
          layout: {
            "line-cap": "round",
            "line-join": "round",
          },
          paint: {
            "line-color": "#84cc16", // Red color for polygon outline
            "line-width": 2, // Line width
            "line-opacity": 1, // Fully opaque outline
          },
        },
        // vertex point halos
        {
          id: "gl-draw-polygon-and-line-vertex-halo-active",
          type: "circle",
          filter: ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["!=", "mode", "static"]],
          paint: {
            "circle-radius": 10,
            "circle-color": "#FFF", // White color for vertex halo
          },
        },
        // vertex points
        {
          id: "gl-draw-polygon-and-line-vertex-active",
          type: "circle",
          filter: ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["!=", "mode", "static"]],
          paint: {
            "circle-radius": 8,
            "circle-color": "#84cc16", // Red color for vertex points
          },
        },
        // Inactive polygon fill
        {
          id: "gl-draw-polygon-fill-static",
          type: "fill",
          filter: ["all", ["==", "$type", "Polygon"], ["==", "mode", "static"]],
          paint: {
            "fill-color": "#3b82f6", // Blue color for inactive polygon fill
            "fill-outline-color": "#3b82f6", // Blue outline
            "fill-opacity": 0.1, // Semi-opaque fill
          },
        },
        // Inactive polygon outline stroke
        {
          id: "gl-draw-polygon-stroke-static",
          type: "line",
          filter: ["all", ["==", "$type", "Polygon"], ["==", "mode", "static"]],
          layout: {
            "line-cap": "round",
            "line-join": "round",
          },
          paint: {
            "line-color": "#3b82f6", // Blue color for inactive polygon outline
            "line-width": 2, // Line width
            "line-opacity": 1, // Fully opaque outline
          },
        },
        // Inactive vertex points
        {
          id: "gl-draw-polygon-and-line-vertex-static",
          type: "circle",
          filter: ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["==", "mode", "static"]],
          paint: {
            "circle-radius": 3,
            "circle-color": "#3BB2D0", // Blue color for inactive vertex points
          },
        },
      ],

      // Set mapbox-gl-draw to draw by default.
      // The user does not have to click the polygon control button first.
      // defaultMode: drawMode,
    })

    mapRef.current.addControl(draw, "top-right")

Expected Behavior

Types compatible

Actual Behavior

image

alamenai avatar Jul 18 '24 12:07 alamenai

Hi, @alamenai. Could you please try the latest GL JS v3.5.2?

stepankuzmin avatar Jul 19 '24 12:07 stepankuzmin

Hi @stepankuzmin , Thank you. Yes, I'll try it this weekend and get back to you.

alamenai avatar Jul 19 '24 14:07 alamenai

I am using "mapbox-gl": "^3.5.2", and getting exactly the same results.

It appears to be related to

  // ...

  getDefaultPosition(): ControlPosition {
    return "top-left"; // Return the default position as a ControlPosition value
  }

  // ...
}```

frankvdp avatar Jul 24 '24 17:07 frankvdp

It seems it's related to the @types/mapbox__mapbox-gl-draw community typings conflict with the first-class GL JS typings.

stepankuzmin avatar Jul 26 '24 12:07 stepankuzmin

I have a PR in for this:

https://github.com/DefinitelyTyped/DefinitelyTyped/pull/70144

brookjordan avatar Jul 30 '24 05:07 brookjordan

I don't know how versioning works, but that MR got merged. You should at least be able to manually set the branch/commit in your package.json.

brookjordan avatar Jul 30 '24 15:07 brookjordan

Apologies from my side. A new error has reared its head.

The update works great when using yarn link, but fails when installing the module the traditional way. MapBox has compiled their code to use Map$1 as the name of the type: I assume due to a build step and a name collision with the global Map type which they also use… The types I’ve created conflict with that Map, causing build errors.

I’m not sure how to fix these. Plus it’s hard to test, as everything works great when woking locally.

Click to see a screenshot of what I see in my IDE

Note that it correctly matches Map with Map$1.

Screenshot 2024-07-31 at 3 38 56 PM

brookjordan avatar Jul 31 '24 07:07 brookjordan

Hi @brookjordan,

Thanks for taking a stab at this. I think you could use the mapboxgl.Map type in DefinitelyTyped instead of Map to avoid collisions.

stepankuzmin avatar Jul 31 '24 08:07 stepankuzmin

Could you help me out with the syntax. The types don’t seem to latch on properly. Maybe the way MapBox has transpiled everything has meant that TypeScript no longer recognises the namespaces?

My attempt was changing from this:

declare module "mapbox-gl" {
    interface Map {
        on<T extends MapboxDraw.DrawEventType>(type: T, listener: (event: EventOf<T>) => void): this;
        off<T extends MapboxDraw.DrawEventType>(type: T, listener: (event: EventOf<T>) => void): this;
    }
}

to this:

declare module "mapbox-gl" {
    namespace mapboxgl {
        interface Map {
            on<T extends MapboxDraw.DrawEventType>(type: T, listener: (event: EventOf<T>) => void): this;
            off<T extends MapboxDraw.DrawEventType>(type: T, listener: (event: EventOf<T>) => void): this;
        }
    }
}

brookjordan avatar Aug 05 '24 07:08 brookjordan

I've run across this while attempting to update the libraries. Is there a workaround? If not, what are the latest versions of @mapbox/mapbox-gl-draw and mapbox-gl that are functional together?

whittaker007 avatar Feb 17 '25 19:02 whittaker007

I've temporarily gotten round this with an ugly typescript hack:

// eslint-disable-next-line no-type-assertion/no-type-assertion
const typeFudgedDrawControl = theDrawControl as unknown as IControl;
map.addControl(typeFudgedDrawControl, 'top-left');

whittaker007 avatar Feb 18 '25 19:02 whittaker007

Issue is still there but the workaround of @whittaker007 helps for now...

but I get some other type issues when doing some basic integration (just selecting the control buttons): Error: layers.gl-draw-lines.cold.paint.line-dasharray[2][0]: Expression name must be a string, but found number instead. If you wanted a literal array, use ["literal", [...]]. at Object.as [as y] (tslib.es6.js:115:1) at xi (mat2.js:13:1) at wi._validate (mat2.js:13:1) at wi.addLayer (mat2.js:13:1) at push../node_modules/maplibre-gl/dist/maplibre-gl.js.e.Map.addLayer (mat2.js:13:1) at mode_handler.js:2:1 at Array.forEach () at Object.addLayers (mode_handler.js:2:1) at push../node_modules/maplibre-gl/dist/maplibre-gl.js.e.Map.connect (mode_handler.js:2:1) at push../node_modules/maplibre-gl/dist/maplibre-gl.js.e.Map.fire (tslib.es6.js:115:1)

apparently the lib is not compatible with the latest version of MapLibre-GL ("maplibre-gl": "^5.6.1", "@mapbox/mapbox-gl-draw": "^1.5.0", "@types/mapbox__mapbox-gl-draw": "^1.4.9")

hannes011 avatar Jul 21 '25 12:07 hannes011