Валидация географических координат в прикладных JavaScript и TypeScript-приложениях опирается на строгие математические диапазоны значений. Широта и долгота представляют собой числовые величины, которые должны соответствовать геодезическим ограничениям: широта варьируется в диапазоне от -90 до 90, долгота — от -180 до 180. Нарушение этих границ делает координаты некорректными и потенциально опасными для дальнейшей обработки в геоинформационных системах, API карт и сервисах маршрутизации.
В библиотеке class-validator предусмотрены специализированные
декораторы для проверки таких значений: @IsLatitude и
@IsLongitude. Они обеспечивают строгую проверку числовых
полей без необходимости ручной реализации диапазонной логики.
Декоратор @IsLatitude применяется к числовым полям,
содержащим значение широты. Проверка основана на математическом
диапазоне допустимых значений:
Любое значение, выходящее за пределы этого интервала, считается невалидным.
Проверка включает несколько уровней:
Внутри class-validator используется строгая логика сравнения, исключающая пограничные ошибки при обработке входных данных из HTTP-запросов.
import { IsLatitude } from 'class-validator';
export class LocationDto {
@IsLatitude()
lat: number;
}
В этом случае любое значение вне диапазона [-90, 90] приведёт к ошибке валидации.
При использовании совместно с class-transformer возможно
преобразование входных данных:
import { Type } from 'class-transformer';
import { IsLatitude } from 'class-validator';
export class LocationDto {
@Type(() => Number)
@IsLatitude()
lat: number;
}
Это позволяет корректно обрабатывать значения, поступающие из HTTP payload в виде строк.
По умолчанию формируется стандартное сообщение, однако возможно переопределение:
import { IsLatitude } from 'class-validator';
export class LocationDto {
@IsLatitude({ message: 'Недопустимое значение широты' })
lat: number;
}
Декоратор @IsLongitude предназначен для проверки
долготы. Допустимый диапазон значений:
Логика проверки аналогична @IsLatitude, но с другим
числовым интервалом.
import { IsLongitude } from 'class-validator';
export class LocationDto {
@IsLongitude()
lng: number;
}
import { Type } from 'class-transformer';
import { IsLongitude } from 'class-validator';
export class LocationDto {
@Type(() => Number)
@IsLongitude()
lng: number;
}
Чаще всего координаты используются в паре, формируя географическую точку. В таких случаях оба декоратора применяются одновременно в одном DTO.
import { IsLatitude, IsLongitude } from 'class-validator';
import { Type } from 'class-transformer';
export class CoordinatesDto {
@Type(() => Number)
@IsLatitude()
lat: number;
@Type(() => Number)
@IsLongitude()
lng: number;
}
Такое представление обеспечивает целостность данных на уровне модели.
В реальных приложениях координаты часто приходят:
На уровне HTTP данные нередко представлены строками, что требует
дополнительного преобразования типов. Без использования
class-transformer возможны ложные срабатывания или пропуск
ошибок.
Типичный сценарий некорректных данных:
"91" для широты"200" для долготы"NaN"Декораторы @IsLatitude и @IsLongitude
обеспечивают единообразную обработку подобных случаев при корректной
конфигурации трансформации.
В экосистеме NestJS валидация координат часто выполняется
автоматически через ValidationPipe.
import { ValidationPipe } from '@nestjs/common';
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
}),
);
При такой конфигурации:
Географические координаты являются примером ограниченных числовых доменов. В отличие от произвольных чисел, здесь критически важна геометрическая корректность:
Декораторы реализуют эти ограничения как чистую проверку диапазона без геопространственных преобразований.
Особое внимание требуется при работе с граничными значениями:
Примеры корректных случаев:
lat = 90 // Северный полюс
lat = -90 // Южный полюс
lng = 180 // линия смены даты
lng = -180 // та же линия в противоположной записи
Если значение не может быть интерпретировано как число, валидация завершается ошибкой:
При этом важно учитывать порядок применения декораторов: трансформация должна выполняться до валидации.
class-validator позволяет задавать контекстные сообщения, что особенно полезно при построении API:
@IsLatitude({ message: 'Широта должна находиться в диапазоне от -90 до 90 градусов' })
lat: number;
@IsLongitude({ message: 'Долгота должна находиться в диапазоне от -180 до 180 градусов' })
lng: number;
Координаты часто являются частью более сложных моделей:
import { IsLatitude, IsLongitude } from 'class-validator';
import { Type } from 'class-transformer';
class GeoPointDto {
@Type(() => Number)
@IsLatitude()
latitude: number;
@Type(() => Number)
@IsLongitude()
longitude: number;
}
class PlaceDto {
name: string;
location: GeoPointDto;
}
При такой структуре валидируется не только примитивное значение, но и вложенный объект координат.
Распространённые проблемы при работе с декораторами координат:
При использовании массивов координат применяется дополнительная настройка:
import { ValidateNested, IsLatitude, IsLongitude } from 'class-validator';
import { Type } from 'class-transformer';
class PointDto {
@IsLatitude()
lat: number;
@IsLongitude()
lng: number;
}
class RouteDto {
@ValidateNested({ each: true })
@Type(() => PointDto)
points: PointDto[];
}
Каждый элемент массива проходит независимую валидацию.
@IsLatitude и @IsLongitude не
выполняют:
Они ограничиваются исключительно проверкой диапазона чисел, оставляя геодезическую интерпретацию на уровне прикладной логики или специализированных библиотек.