@IsCurrency

Декоратор @IsCurrency используется для валидации строковых значений, представляющих денежные суммы в различных форматах валют. Проверка охватывает корректность символа валюты, расположение знака, разделители тысяч и дробной части, а также допустимость отрицательных значений.

Основная задача — обеспечение строгого соответствия входных данных финансовому формату, исключающему неоднозначные или некорректные представления денежных значений.


Поведение валидатора

Проверка выполняется над строковым значением и включает несколько этапов:

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

Значение считается валидным только при полном соответствии всем активным правилам.


Сигнатура и параметры

import { IsCurrency } from 'class-validator';

@IsCurrency(options?: IsCurrencyOptions)

IsCurrencyOptions определяет правила валидации формата:

interface IsCurrencyOptions {
  symbol?: string;
  require_symbol?: boolean;
  allow_space_after_symbol?: boolean;
  symbol_after_digits?: boolean;
  allow_negatives?: boolean;
  thousands_separator?: string;
  decimal_separator?: string;
}

Параметры конфигурации

symbol

Определяет ожидаемый символ валюты.

Примеры:

  • $

Если символ задан, строка обязана ему соответствовать.


require_symbol

Управляет обязательностью валютного символа.

  • true — символ обязателен;
  • false — допускаются числовые значения без символа.

allow_space_after_symbol

Разрешает пробел между символом и числом.

Примеры допустимых форм:

  • $100
  • $ 100

symbol_after_digits

Определяет расположение символа относительно числа.

  • false — символ перед числом ($100);
  • true — символ после числа (100$).

allow_negatives

Контролирует поддержку отрицательных значений.

  • true — допускаются -100, -$100;
  • false — отрицательные значения считаются невалидными.

thousands_separator

Задает символ разделителя тысяч.

Примеры:

  • ,1,000
  • .1.000
  • пробел → 1 000

Несоответствие разделителя приводит к ошибке валидации.


decimal_separator

Определяет символ отделения дробной части.

Примеры:

  • .10.50
  • ,10,50

Используется совместно с thousands_separator, формируя строгий формат числа.


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

import { IsCurrency } from 'class-validator';

class PaymentDto {
  @IsCurrency()
  amount: string;
}

В этом случае применяется стандартный набор правил без строгой привязки к конкретной валюте.


Пример с фиксированным символом валюты

class PaymentDto {
  @IsCurrency({
    symbol: '$',
    require_symbol: true,
  })
  amount: string;
}

Допустимые значения:

  • $100
  • $100.00

Недопустимые:

  • 100
  • €100

Пример с отрицательными значениями

class AccountDto {
  @IsCurrency({
    symbol: '€',
    allow_negatives: true,
  })
  balance: string;
}

Допустимые значения:

  • €100
  • -€100

Форматы с разделителями

class ReportDto {
  @IsCurrency({
    symbol: '₽',
    thousands_separator: ' ',
    decimal_separator: ',',
  })
  total: string;
}

Корректные значения:

  • ₽1 000,50
  • ₽10 000

Некорректные:

  • ₽1000.50
  • ₽1,000.50

Расположение символа после числа

class CustomDto {
  @IsCurrency({
    symbol: 'USD',
    symbol_after_digits: true,
  })
  amount: string;
}

Допустимые значения:

  • 100USD

Недопустимые:

  • USD100

Комбинация правил

class ComplexDto {
  @IsCurrency({
    symbol: '$',
    require_symbol: true,
    allow_space_after_symbol: true,
    allow_negatives: false,
    thousands_separator: ',',
    decimal_separator: '.',
  })
  price: string;
}

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

  • $100
  • $ 1,000.00

Примеры невалидных:

  • 1000
  • $1.000,00
  • -$100

Особенности обработки

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

Типичные ошибки конфигурации

Несоответствие разделителей

thousands_separator: ',',
decimal_separator: '.'

Вход: 1.000,00 → невалидно из-за обратного порядка разделителей.


Конфликт расположения символа

symbol: '$',
symbol_after_digits: true

Вход: $100 → невалидно, так как символ должен быть после числа.


Отсутствие обязательного символа

require_symbol: true

Вход: 100 → не проходит проверку независимо от числа.


Интеграция в DTO-структуры

Валидация денежных значений часто применяется в DTO-слоях для обеспечения корректности входных данных перед бизнес-логикой:

  • платежные системы;
  • финансовые отчеты;
  • расчеты стоимости;
  • учетные системы;
  • API интернет-магазинов.

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


Поведение при трансформации данных

@IsCurrency не выполняет преобразование типов. Он работает исключительно как валидатор строкового представления. Приведение к числу осуществляется отдельно, если требуется дальнейшая математическая обработка значения.


Влияние локализации

Поддержка форматов с различными разделителями позволяет адаптировать валидацию под региональные стандарты:

  • европейский формат: 1.000,00;
  • американский формат: 1,000.00;
  • смешанные пользовательские форматы через кастомные параметры.

Гибкость достигается за счет ручной настройки параметров, а не автоматического определения локали.