@IsMobilePhone

Декоратор @IsMobilePhone в библиотеке class-validator используется для проверки строкового значения на соответствие формату мобильного телефонного номера. Проверка основана на правилах библиотеки validator.js, которая предоставляет набор предопределённых региональных форматов и стандартов валидации телефонных номеров.

Основное назначение — контроль корректности телефонных данных в DTO-моделях, особенно в серверных приложениях, где требуется строгая валидация входящих данных (например, в API на основе NestJS или Express с классами DTO).


Базовое использование

Минимальная конфигурация предполагает только применение декоратора без дополнительных параметров:

import { IsMobilePhone } from 'class-validator';

export class CreateUserDto {
  @IsMobilePhone()
  phone: string;
}

В этом случае валидация будет использовать дефолтный набор локалей, что может привести к слишком широкому или недостаточно точному контролю формата.


Проверка по локали

Одним из ключевых параметров является указание локали (регионального формата). Это позволяет ограничить допустимые номера определённой страной или набором стран.

import { IsMobilePhone } from 'class-validator';

export class CreateUserDto {
  @IsMobilePhone('ru-RU')
  phone: string;
}

В данном примере допустимыми будут только номера, соответствующие российскому формату мобильных телефонов.


Поддерживаемые форматы локалей

validator.js поддерживает множество локалей. Среди часто используемых:

  • ru-RU — Россия
  • en-US — США
  • en-GB — Великобритания
  • de-DE — Германия
  • fr-FR — Франция
  • any — широкий режим, допускающий различные международные форматы

Пример использования универсальной проверки:

@IsMobilePhone('any')
phone: string;

Режим any снижает строгость проверки и подходит для систем, где номера приходят из разных стран.


Опция строгого режима

Второй параметр декоратора позволяет включить строгую проверку формата:

@IsMobilePhone('ru-RU', { strictMode: true })
phone: string;

Поведение strictMode:

  • требует более точного соответствия формату
  • уменьшает вероятность принятия «похожих» строк
  • может отклонять валидные, но нестандартно записанные номера

Без strictMode библиотека допускает более гибкий разбор строки.


Примеры валидных и невалидных значений

Пример для ru-RU

@IsMobilePhone('ru-RU')
phone: string;

Валидные значения:

  • +79991234567
  • 89991234567

Невалидные значения:

  • 12345
  • +1 999 123 45 67
  • phone123

Пример для en-US

@IsMobilePhone('en-US')
phone: string;

Валидные значения:

  • +12025550123
  • 2025550123

Невалидные значения:

  • +44 7700 900123
  • +999999

Поведение с пустыми значениями

Декоратор @IsMobilePhone не рассматривает пустую строку как валидное значение. Однако поведение зависит от комбинации с другими декораторами:

import { IsOptional, IsMobilePhone } from 'class-validator';

export class UpdateUserDto {
  @IsOptional()
  @IsMobilePhone('ru-RU')
  phone?: string;
}

В этом случае поле может отсутствовать, но если оно присутствует — обязано соответствовать формату.


Использование в DTO и слоях API

Наиболее распространённый сценарий — валидация входных данных API.

import { IsMobilePhone, IsString } from 'class-validator';

export class RegisterDto {
  @IsString()
  name: string;

  @IsMobilePhone('ru-RU')
  phone: string;
}

Валидация выполняется до попадания данных в бизнес-логику, что снижает необходимость ручных проверок в сервисах.


Поведение при некорректных данных

При использовании ValidationPipe (например, в NestJS) некорректные значения приводят к ошибке валидации:

{
  "statusCode": 400,
  "message": [
    "phone must be a valid phone number"
  ],
  "error": "Bad Request"
}

Сообщение может быть переопределено через параметр message:

@IsMobilePhone('ru-RU', {}, { message: 'Некорректный номер телефона' })
phone: string;

Взаимодействие с другими декораторами

@IsMobilePhone часто комбинируется с другими валидаторами:

import { IsMobilePhone, Length } from 'class-validator';

export class UserDto {
  @Length(10, 15)
  @IsMobilePhone('any')
  phone: string;
}

Однако такое сочетание может привести к конфликтам логики, если длина номера зависит от региона.


Ограничения и особенности реализации

Зависимость от validator.js

Проверка не реализуется вручную в class-validator, а делегируется библиотеке validator.js. Это означает:

  • поведение зависит от версии validator.js
  • обновления могут менять допустимые форматы
  • возможны различия между версиями Node.js окружения

Нестандартизированные форматы

Следующие случаи часто не проходят проверку:

  • номера с пробелами в нестандартных местах без strictMode
  • локальные форматы без кода страны (в зависимости от региона)
  • номера с дополнительными символами (ext, доб.)

Формат E.164 и его роль

Хотя @IsMobilePhone не строго ограничен E.164, многие валидные номера соответствуют этому стандарту:

+79991234567

E.164 предполагает:

  • знак +
  • код страны
  • национальный номер без разделителей

Использование strictMode приближает поведение к E.164-подобной проверке, но не полностью заменяет её.


Типичные ошибки при использовании

Отсутствие указания локали

@IsMobilePhone()
phone: string;

Проблема: слишком широкая проверка, возможны неожиданные валидные форматы.


Использование any без необходимости

@IsMobilePhone('any')
phone: string;

Проблема: отсутствие контроля региональных стандартов.


Конфликт с кастомной нормализацией

Если номер предварительно изменяется (например, удаляются символы +, пробелы), результат может перестать соответствовать валидатору.


Рекомендации по интеграции в архитектуру

Валидация через @IsMobilePhone эффективнее всего работает на уровне DTO:

  • входящие HTTP-запросы
  • данные из внешних API
  • формы регистрации и профилей

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


Поведение в строгих API-схемах

В системах с жёсткими контрактами (например, microservices или GraphQL DTO) использование @IsMobilePhone снижает вероятность попадания неконсистентных данных между сервисами. Особенно это важно при хранении телефонов в унифицированном формате для:

  • SMS-рассылок
  • двухфакторной аутентификации
  • CRM-интеграций