I'm trying to integrate a map from MapBox (or maplibre) within a VueJS component.
The thing is, I need to declare my map in the data part, but the div that will contain my map is not initialized yet. So I have to instantiate my Map inside the mounted()
block.
I've tried this:
<template>
<div id="mapContainer" class="basemap"></div>
</template>
<script lang="ts">
import maplibregl from "maplibre-gl";
import { defineComponent } from "vue";
export default defineComponent({
name: "BaseMap",
data() {
return {
map: null satisfies maplibregl.Map | null,
};
},
mounted() {
this.map = new maplibregl.Map({
container: "mapContainer",
style:
`https://api.maptiler.com/maps/voyager-v2/style.json?key=` +
import.meta.env.VITE_MAP_TOKEN,
center: [15, 56.5],
zoom: 3.6,
});
},
methods(): {},
});
</script>
But I'm getting TS2322: Type 'Map' is not assignable to type 'null'.
and TS2531: Object is possibly 'null'.
on all calls on this.map
.
Is there an easy way to force to type of this.map
or do this in a cleaner way ?
Thanks
satisfies
won't work. It will set the narrowest type it can set, in this case, the type of map
is set to null
.
You can see that error on this simple TypeScript example
let y = null satisfies number | null;
y = 123; // error Type '123' is not assignable to type `null`
I would recommend using an interface to define all the types of the properties in the data
<template>
<div id="mapContainer" class="basemap"></div>
</template>
<script lang="ts">
import maplibregl from "maplibre-gl";
import { defineComponent } from "vue";
interface Data {
map: maplibregl.Map | null;
}
export default defineComponent<Data>({
name: "BaseMap",
data() {
return {
map: null,
};
},
mounted() {
this.map = new maplibregl.Map({
container: "mapContainer",
style:
`https://api.maptiler.com/maps/voyager-v2/style.json?key=` +
import.meta.env.VITE_MAP_TOKEN,
center: [15, 56.5],
zoom: 3.6,
});
},
methods(): {},
});
</script>
For the TS2531: Object is possibly 'null'.
error you need to use either optional chaining (?.
) or non-null assertion (!.
) e.g.
this.map?.moveLayer('id', 'beforeId');
this.map!.moveLayer('id', 'beforeId');