TypeScript поддержка

Архитектура типизации и поставка деклараций

Современные версии CesiumJS распространяются с встроенными TypeScript-типами, что исключает необходимость установки внешних пакетов @types/cesium. Типы поставляются вместе с библиотекой и синхронизированы с исходным API, что снижает риск рассинхронизации между реализацией и декларациями.

Типизация охватывает ключевые подсистемы:

  • Viewer и его конфигурации
  • Scene, Camera, Globe
  • сущности Entity и их свойства
  • примитивы (Primitive, GeometryInstance)
  • источники данных (GeoJsonDataSource, KmlDataSource)
  • математическое ядро (Cartesian3, Matrix4, Quaternion)

Типы расположены в пакете cesium и экспортируются напрямую через ESM-границы.


Базовая интеграция TypeScript-проекта

Использование CesiumJS в TypeScript-проекте предполагает корректную настройку компилятора и сборщика модулей.

Установка зависимостей

npm install cesium

Конфигурация tsconfig.json

Ключевым моментом является поддержка современных модулей и разрешение типов из node_modules.

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "types": ["cesium"]
  }
}

Особенности конфигурации:

  • skipLibCheck снижает вероятность конфликтов между сложными геометрическими типами
  • moduleResolution: "Bundler" необходим при использовании Vite, Webpack 5 или esbuild
  • строгий режим (strict) особенно важен для работы с геометрией и координатами

Импорт CesiumJS в TypeScript

Cesium использует модульную структуру ES, поэтому импорт осуществляется напрямую:

import {
  Viewer,
  Cartesian3,
  Color,
  Entity
} from "cesium";

При использовании сборщиков требуется учитывать ресурсы Cesium (Workers, Assets, Widgets), которые не входят в стандартный бандл и должны быть отдельно настроены.


Типизация ключевых объектов

Viewer

Viewer является центральной точкой управления сценой и типизирован как класс с обширным набором опций:

const viewer: Viewer = new Viewer("cesiumContainer", {
  terrainProvider: undefined,
  animation: false,
  timeline: false
});

Основные типизированные поля:

  • scene: Scene
  • camera: Camera
  • entities: EntityCollection

Entity и строгая модель данных

Entity API полностью типизирована и использует декларативную модель описания объектов.

const entity: Entity = viewer.entities.add({
  position: Cartesian3.fromDegrees(30.5, 50.4, 1000),
  point: {
    pixelSize: 10,
    color: Color.RED
  }
});

Типизация обеспечивает:

  • контроль координатных систем
  • проверку допустимых визуальных свойств
  • автодополнение вложенных структур (например, billboard, label, path)

Геометрические типы и математическое ядро

CesiumJS активно использует строгие математические типы для 3D-вычислений.

Cartesian3

const position: Cartesian3 = Cartesian3.fromDegrees(55.75, 37.61, 500);

Тип гарантирует корректное использование 3D-векторов в сцене.

Matrix4

import { Matrix4 } from "cesium";

const transform: Matrix4 = Matrix4.IDENTITY;

Используется для преобразований объектов в мировом пространстве.


Работа с данными через типизированные источники

GeoJSON

import { GeoJsonDataSource } from "cesium";

const dataSource: GeoJsonDataSource = await GeoJsonDataSource.load(
  "/data/map.geojson"
);

viewer.dataSources.add(dataSource);

Типизация обеспечивает:

  • корректную структуру FeatureCollection
  • автоматическое распознавание свойств геометрии
  • поддержку стилизации через strongly typed properties

Интеграция с современными сборщиками

Vite

Cesium требует настройки статических ресурсов:

import { defineConfig } from "vite";
import cesium from "vite-plugin-cesium";

export default defineConfig({
  plugins: [cesium()]
});

Типы при этом не требуют дополнительных конфигураций — они подтягиваются из пакета автоматически.


Webpack

const CopyWebpackPlugin = require("copy-webpack-plugin");
const cesiumSource = "node_modules/cesium/Source";

module.exports = {
  resolve: {
    alias: {
      cesium: cesiumSource
    }
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        { from: `${cesiumSource}/Workers`, to: "Workers" },
        { from: `${cesiumSource}/Assets`, to: "Assets" },
        { from: `${cesiumSource}/Widgets`, to: "Widgets" }
      ]
    })
  ]
};

TypeScript при этом продолжает работать поверх обычного JavaScript-бандла без изменений.


Типизация событий и реактивная модель

Cesium предоставляет событийную систему с типизированными callback-функциями.

viewer.camera.changed.addEventListener(() => {
  const position = viewer.camera.position;
});

Типы событий:

  • Event — базовый класс событийной системы
  • строгие сигнатуры callback-ов предотвращают ошибки аргументов

Расширение типов и кастомные интерфейсы

При расширении Entity можно использовать интерфейсы TypeScript для описания доменных моделей:

interface CustomEntityProps {
  id: string;
  altitude: number;
}

const customEntity = viewer.entities.add({
  position: Cartesian3.fromDegrees(10, 10),
  properties: {
    id: "A1",
    altitude: 1200
  }
});

Cesium сохраняет свойства в PropertyBag, который также типизирован.


Типизация времени и интервалов анимации

import { JulianDate } from "cesium";

const time: JulianDate = JulianDate.now();

JulianDate используется для:

  • анимации сцен
  • синхронизации данных
  • временных рядов

Проблемы совместимости типов и их обработка

На практике встречаются следующие ситуации:

Несовпадение версий TypeScript

Cesium чувствителен к строгой типизации, поэтому предпочтительны версии TS >= 4.5.

Конфликты с DOM-типами

Некоторые классы пересекаются с WebGL и DOM API, что требует аккуратной настройки lib:

{
  "compilerOptions": {
    "lib": ["ES2020", "DOM"]
  }
}

Типизация низкоуровневого рендеринга

Cesium предоставляет доступ к WebGL через обёртки:

  • Context
  • ShaderProgram
  • DrawCommand
import { DrawCommand } from "cesium";

const command: DrawCommand = new DrawCommand({
  // параметры отрисовки
});

Эти структуры строго типизированы, поскольку ошибки в них приводят к сбоям GPU-пайплайна.


Модульная модель и tree-shaking с TypeScript

CesiumJS поддерживает ESM-импорты, что позволяет TypeScript-сборщикам выполнять tree-shaking:

  • импортируются только используемые классы
  • исключаются неиспользуемые модули визуализации
  • уменьшается размер финального бандла

Работа с декларациями в пользовательских расширениях

При создании расширений часто требуется расширять глобальные типы Cesium:

declare module "cesium" {
  interface Entity {
    customField?: string;
  }
}

Такой подход интегрирует пользовательскую модель данных в стандартную типизацию API без потери совместимости с обновлениями библиотеки.