TypeScript-проект с использованием MapLibre GL JS начинается с установки основной библиотеки и обеспечения корректной типизации API. Современные версии MapLibre GL JS распространяются с встроенными типами, однако в некоторых конфигурациях сборки может потребоваться явная настройка типов или подключение дополнительных объявлений.
npm install maplibre-gl
При использовании старых сборок или нестандартных окружений дополнительно подключается пакет типов:
npm install -D @types/maplibre-gl
В большинстве современных проектов достаточно одного пакета
maplibre-gl, так как типы поставляются вместе с
библиотекой.
Корректная работа с MapLibre GL JS требует строгой настройки компилятора TypeScript. Основное внимание уделяется DOM-типации, модульной системе и строгому контролю null-значений.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"esModuleInterop": true,
"skipLibCheck": true,
"lib": ["DOM", "ES2020"],
"types": []
},
"include": ["src"]
}
Ключевые моменты конфигурации:
DOM в lib обязателен для работы с
HTMLElement и Map-контейнеромstrict режим предотвращает ошибки при работе с GeoJSON
и стилямиskipLibCheck снижает количество конфликтов в типах
зависимостейmoduleResolution: Bundler предпочтителен при
использовании Vite, Webpack 5 и аналогичных инструментовБиблиотека поддерживает ESM-импорт, что упрощает работу в современных сборщиках.
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
Тип maplibregl.Map автоматически доступен после
импорта.
Основная точка входа — класс Map. TypeScript позволяет
строго типизировать параметры и события.
const map = new maplibregl.Map({
container: "map",
style: "https://demotiles.maplibre.org/style.json",
center: [30.31413, 59.93863],
zoom: 10
});
Типы параметров:
container: string | HTMLElementstyle: StyleSpecification | stringcenter: [number, number]zoom: numberMapLibre GL JS активно использует GeoJSON, поэтому TypeScript требует корректного описания географических данных.
import type { Feature, FeatureCollection, Point } from "geojson";
const point: Feature<Point> = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [30.31413, 59.93863]
},
properties: {
name: "Center point"
}
};
Использование строгих типов предотвращает ошибки в порядке координат и структуре объектов.
Источники данных в MapLibre GL JS строго типизированы через
GeoJSONSourceSpecification.
map.on("load", () => {
map.addSource("points", {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
});
});
Для сложных проектов используется явное приведение типа:
import type { GeoJSONSourceSpecification } from "maplibre-gl";
const source: GeoJSONSourceSpecification = {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
};
map.addSource("points", source);
Слои описываются через LayerSpecification. TypeScript
позволяет строго контролировать структуру слоя.
map.addLayer({
id: "points-layer",
type: "circle",
source: "points",
paint: {
"circle-radius": 6,
"circle-color": "#ff0000"
}
});
Типизация предотвращает ошибки в ключах paint и
layout, которые чувствительны к названию и контексту
слоя.
MapLibre GL JS использует событийную модель, где TypeScript помогает безопасно работать с контекстом событий.
map.on("click", (e) => {
console.log(e.lngLat.lng, e.lngLat.lat);
});
Для более строгой типизации событий:
map.on("click", (e: maplibregl.MapMouseEvent & maplibregl.EventData) => {
const coordinates: [number, number] = [e.lngLat.lng, e.lngLat.lat];
});
Типизация событий особенно важна при работе с
queryRenderedFeatures:
map.on("click", (e) => {
const features = map.queryRenderedFeatures(e.point);
});
В TypeScript-проектах часто требуется хранить ссылку на карту с
учётом возможного null.
let map: maplibregl.Map | null = null;
function initMap(): void {
map = new maplibregl.Map({
container: "map",
style: "https://demotiles.maplibre.org/style.json"
});
}
Защита от null обязательна при дальнейших вызовах:
if (map) {
map.setZoom(12);
}
Vite автоматически поддерживает ESM и TypeScript, дополнительные настройки минимальны.
import maplibregl from "maplibre-gl";
CSS импортируется напрямую:
import "maplibre-gl/dist/maplibre-gl.css";
При использовании Webpack требуется корректная обработка CSS и TypeScript:
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
}
};
TypeScript позволяет расширять типы MapLibre GL JS при добавлении пользовательских слоёв, контролов или свойств.
declare module "maplibre-gl" {
interface Map {
customMethod?: () => void;
}
}
Это особенно полезно при создании архитектурных надстроек над картой.
Контролы реализуются через интерфейс IControl.
class ZoomInfoControl implements maplibregl.IControl {
private container!: HTMLElement;
onAdd(map: maplibregl.Map): HTMLElement {
this.container = document.createElement("div");
this.container.className = "zoom-info";
this.container.textContent = "Zoom control";
return this.container;
}
onRemove(): void {
this.container.remove();
}
}
Добавление контролов:
map.addControl(new ZoomInfoControl());
Стиль карты описывается через StyleSpecification, что
позволяет полностью контролировать структуру JSON-стиля.
import type { StyleSpecification } from "maplibre-gl";
const style: StyleSpecification = {
version: 8,
sources: {},
layers: []
};
Такой подход снижает вероятность ошибок в сложных кастомных стилях.
TypeScript помогает выявлять несоответствия, однако некоторые ошибки возникают только во время выполнения. Для MapLibre GL JS характерны следующие защитные паттерны:
map.on("styledata", () => {
const source = map.getSource("points");
if (!source) return;
});
Явные проверки обязательны при работе с динамическими источниками и слоями.
Использование TypeScript с MapLibre GL JS снижает количество runtime-ошибок при:
Строгая типизация также упрощает масштабирование проекта, особенно при наличии множества слоёв и динамических данных.