Интервалы и диапазоны

Поддержка интервалов и диапазонов в i18next строится на сочетании интерполяции, плюрализации и расширяемых постпроцессоров, позволяющих описывать не только одиночные значения, но и целые числовые и семантические диапазоны. Такой подход закрывает задачи от простых чисел до сложных форматов вроде «1–5 элементов», «6+ элементов», «в течение 2–3 дней», «0–10 сообщений» и подобных конструкций, зависящих от локали.


Интерполяция как базовый механизм диапазонов

Интерполяция в i18next служит фундаментом для работы с динамическими значениями, включая диапазоны.

Типичный пример:

{
  "items": "Есть {{count}} элемент"
}
i18next.t('items', { count: 5 })

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

Расширенный пример:

{
  "range": "Элементов: {{min}}–{{max}}"
}
i18next.t('range', { min: 1, max: 10 })

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


Плюрализация как основа диапазонной логики

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

{
  "item": "{{count}} элемент",
  "item_plural": "{{count}} элементов"
}
i18next.t('item', { count: 3 })

Внутренний механизм выбирает форму на основе правил CLDR для конкретного языка. Однако плюрализация работает по дискретным категориям (one, few, many, other), а не по произвольным числовым диапазонам.


Интервальные ключи и диапазонные формы

Для задач, где требуется не только «один / много», применяется расширение через ключи с диапазонами или суффиксами.

Типовой паттерн:

{
  "items_0": "Нет элементов",
  "items_1": "1 элемент",
  "items_2_4": "{{count}} элемента",
  "items_5_10": "{{count}} элементов",
  "items_11_plus": "{{count}} элементов"
}

Далее диапазон выбирается логикой приложения:

function getKey(count) {
  if (count === 0) return 'items_0'
  if (count === 1) return 'items_1'
  if (count >= 2 && count <= 4) return 'items_2_4'
  if (count >= 5 && count <= 10) return 'items_5_10'
  return 'items_11_plus'
}

i18next.t(getKey(7), { count: 7 })

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


Interval plural postprocessor

Расширение через i18next-intervalplural-postprocessor вводит более декларативную модель диапазонов.

Формат ключей:

{
  "key_interval": "(1,5) яблок",
  "key_interval_2": "(5,10) яблок",
  "key_interval_3": "(10,+Inf) яблок"
}

Синтаксис интервалов обычно включает:

  • (a,b) — открытый интервал
  • [a,b] — закрытый интервал
  • (a,b] или [a,b) — полуоткрытые интервалы
  • +Inf — бесконечность

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

i18next.t('key', { postProcess: 'interval', count: 7 })

Постпроцессор анализирует count и выбирает соответствующий интервал автоматически.


Совмещение интервалов и плюрализации

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

{
  "messages_interval": "(0) нет сообщений",
  "messages_interval_1": "(1) {{count}} сообщение",
  "messages_interval_2": "(2,4) {{count}} сообщения",
  "messages_interval_3": "(4,+Inf) {{count}} сообщений"
}

Такой подход объединяет:

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

Диапазоны дат и времени

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

Строковые диапазоны

{
  "date_range": "{{start}} — {{end}}"
}
i18next.t('date_range', {
  start: '01.05.2026',
  end: '10.05.2026'
})

Форматирование через интерполяцию

{
  "date_range": "{{start, date}} — {{end, date}}"
}

Где форматтер date реализуется через interpolation.format.


Форматтеры для диапазонных значений

Форматтеры позволяют нормализовать диапазоны перед выводом.

Пример:

i18next.init({
  interpolation: {
    format: (value, format) => {
      if (format === 'range') {
        return `${value.min}-${value.max}`
      }
      return value
    }
  }
})

Использование:

{
  "range": "Значения: {{value, range}}"
}
i18next.t('range', { value: { min: 3, max: 8 } })

Числовые диапазоны и бизнес-логика

При работе с диапазонами важно учитывать, что система переводов не должна содержать сложную логику сравнения. В i18next перевод остаётся декларативным слоем, тогда как вычисление диапазона выполняется на уровне приложения.

Типичный раздел ответственности:

  • приложение определяет диапазон (min/max, interval key)
  • i18next выбирает локализованную строку
  • форматтеры преобразуют данные в строку

Особенности локалей при интервалах

Разные языки по-разному трактуют числовые диапазоны:

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

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


Сложные композиции диапазонов

В продвинутых сценариях диапазоны комбинируются с вложенными объектами:

{
  "stats": {
    "users": "(0) нет пользователей | (1,5) {{count}} пользователя | (5,+Inf) {{count}} пользователей",
    "errors": "(0) без ошибок | (1,+Inf) {{count}} ошибок"
  }
}

Такой формат позволяет описывать поведение интерфейса компактно, сохраняя читаемость переводов.


Производительность при использовании интервалов

При большом количестве диапазонных ключей важны следующие аспекты:

  • минимизация вычислений в postProcess
  • кэширование результатов t()
  • избегание динамического построения ключей в горячих циклах
  • использование статических интервалов вместо вычисляемых строк

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


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

  • попытка реализовать бизнес-логику внутри translation keys
  • смешивание интервалов и плюрализации без чёткой стратегии
  • отсутствие покрытия крайних значений (0, отрицательные числа, Infinity)
  • несогласованность диапазонов между языковыми файлами
  • использование строковых сравнений вместо числовых интервалов

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


Практика структурирования диапазонов

Часто используется единый стиль:

  • 0 — отдельный ключ
  • 1 — отдельный ключ
  • 2–4 — малый диапазон
  • 5–20 — средний диапазон
  • 20+ — общий случай

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