Turf.js изначально проектировался как библиотека для работы с геоданными в формате GeoJSON, что естественным образом делает его хорошо совместимым с TypeScript. Типизация в данном контексте решает две ключевые задачи: строгую проверку геометрических структур и безопасную работу с функциями пространственного анализа.
Основой типовой системы Turf.js выступают стандарты GeoJSON,
формализованные через набор интерфейсов: Feature,
FeatureCollection, Geometry, а также
конкретные геометрические типы (Point,
Polygon, LineString и другие).
TypeScript-экосистема Turf.js опирается на типы GeoJSON, определяющие структуру геометрических объектов.
import { Feature } fr om "geojson";
const point: Feature = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [30.5, 50.5],
},
properties: {},
};
Feature представляет собой контейнер, который объединяет
геометрию и произвольные свойства. В строгой типизации важно учитывать,
что geometry может быть null.
import { FeatureCollection } from "geojson";
const collection: FeatureCollection = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [10, 20],
},
properties: {},
},
],
};
FeatureCollection используется для группировки множества
геообъектов и является основным форматом входных и выходных данных
большинства функций Turf.js.
import { Point, Polygon, LineString } from "geojson";
const p: Point = {
type: "Point",
coordinates: [0, 0],
};
Каждый геометрический тип строго фиксирует структуру координат:
Point → [number, number]LineString → number[][]Polygon → number[][][]В Turf.js координаты всегда представлены в формате
[longitude, latitude], что принципиально важно при строгой
типизации.
type Position = [number, number];
const coord: Position = [37.6173, 55.7558];
Ошибки порядка координат не выявляются TypeScript на уровне типов, что делает необходимым введение дополнительных утилитарных типов или runtime-проверок.
Функции Turf.js в TypeScript обычно принимают строго типизированные
GeoJSON-объекты и возвращают новые Feature.
turf.pointimport point from "@turf/point";
const p = point([10, 20]);
Тип результата:
Feature<Point>
turf.bufferimport buffer from "@turf/buffer";
import { point } from "@turf/helpers";
const pt = point([30, 10]);
const result = buffer(pt, 50, { units: "kilometers" });
Тип результата:
Feature<Polygon>
TypeScript выводит тип на основании входной геометрии, однако в некоторых случаях требуется явное указание дженериков.
Некоторые функции используют дженерики для сохранения типа входного Feature.
import { Feature, Point } from "geojson";
import centroid from "@turf/centroid";
const input: Feature<Point> = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [0, 0],
},
properties: {},
};
const result = centroid(input);
Тип результата:
Feature<Point>
Однако для сложных операций результат может быть изменён, например
Point → Polygon.
properties в GeoJSON по умолчанию имеют тип:
Record<string, any>
Это создаёт слабое место в типизации Turf.js, которое часто уточняется вручную.
interface MyProps {
name: string;
population: number;
}
import { Feature } from "geojson";
const city: Feature<Point, MyProps> = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [10, 20],
},
properties: {
name: "City",
population: 100000,
},
};
Такой подход обеспечивает контроль структуры данных на уровне компиляции.
Turf.js активно использует перегрузки функций для поддержки разных типов входных данных.
turf.distanceimport distance from "@turf/distance";
const a = [0, 0];
const b = [10, 10];
const d = distance(a, b, { units: "kilometers" });
Функция принимает:
PositionFeature<Point>Geometry<Point>TypeScript объединяет эти варианты через union-типы:
type AllPoints = Position | Feature<Point> | Point;
Несмотря на поддержку TypeScript, библиотека имеет ряд типовых ограничений:
const wrong = point(["invalid" as any, 20]);
TypeScript не предотвращает runtime-ошибку без дополнительных ограничений.
any
в утилитахНекоторые вспомогательные функции используют обобщённые
any для properties.
После трансформаций тип часто становится:
Feature<Geometry, any>
что снижает пользу строгой типизации.
import { Feature, Point } from "geojson";
import { point } from "@turf/helpers";
interface UserProps {
id: number;
}
type UserPoint = Feature<Point, UserProps>;
function createUserPoint(
coords: [number, number],
props: UserProps
): UserPoint {
return {
...point(coords),
properties: props,
};
}
Включение строгого режима усиливает контроль:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}
В этом режиме:
null в geometryanyНекоторые операции возвращают разные типы в зависимости от входа:
Feature<Point> | Feature<Polygon>
Это характерно для:
intersectuniondifferenceunionimport union from "@turf/union";
const result = union(poly1, poly2);
Тип результата:
Feature<Polygon | MultiPolygon> | null
import { FeatureCollection } from "geojson";
import centroid from "@turf/centroid";
function process(fc: FeatureCollection) {
return fc.features.map((f) => centroid(f));
}
Тип результата:
Feature<Point>[]
При построении сложных систем анализа часто вводятся доменные типы поверх GeoJSON.
type Road = Feature<LineString, { speedLim it: number }>;
type Building = Feature<Polygon, { floors: number }>;
Это позволяет связывать геометрию с бизнес-логикой без потери типовой строгости.
Turf.js поддерживает модульный импорт:
import area from "@turf/area";
import length from "@turf/length";
TypeScript корректно типизирует каждый модуль отдельно, что снижает:
import buffer from "@turf/buffer";
import { point } from "@turf/helpers";
const p = point([0, 0]);
const poly = buffer(p, 10, { units: "meters" });
Тип результата:
Feature<Polygon>
TypeScript фиксирует изменение геометрии, но не отслеживает семантическую корректность.
Типовая система Turf.js может быть сведена к нескольким уровням:
Feature,
Geometry)Point,
Polygon)Эта модель обеспечивает баланс между гибкостью геоалгоритмов и статической безопасностью TypeScript, сохраняя совместимость с динамическими сценариями пространственного анализа.