В библиотеке Globalize типизация форматтеров опирается на разделение ответственности между механизмом локализации и контрактом возвращаемого значения. Форматтер в контексте Globalize представляет собой фабрику функций, где итоговый результат строго предопределён типом входных данных, набором CLDR-правил и выбранной локалью.
Архитектура форматтеров строится вокруг идеи неизменяемого контракта: каждый форматтер возвращает значение фиксированного типа, зависящее от категории форматирования. Несмотря на динамическую природу JavaScript, внутренняя модель Globalize организует форматтеры как строго специализированные функции, ограниченные доменной областью.
Форматтер создаётся один раз и затем используется многократно, при этом его сигнатура остаётся стабильной:
Типизация в данном контексте выражается не через язык выполнения, а через контракт поведения.
Форматтеры Globalize можно рассматривать как функции следующего вида:
Formatter<TInput, TResult>Где:
TInput — тип входных данных (number, Date, string,
object);TResult — всегда строка в большинстве прикладных
сценариев.Ключевой особенностью является унификация результата: независимо от локали и настроек форматирования итоговое значение приводится к строковому представлению.
Это создаёт предсказуемую модель:
Числовые форматтеры являются наиболее типизированной частью системы. Их контракт можно формализовать следующим образом:
numberstringЧисловой форматтер учитывает:
Типизация проявляется в том, что форматтер не допускает неоднозначных входных типов. Передача строки или объекта приводит к приведению или ошибке на уровне применения, но не на уровне самой функции.
Пример логики типового контракта:
numberFormatter() → функция
(n: number) => stringОсобенность заключается в том, что тип результата не зависит от локали, хотя семантически меняется его содержание.
Форматтеры дат в Globalize используют аналогичную модель строгого преобразования:
DatestringНесмотря на наличие различных шаблонов (short, medium, long, full), тип возвращаемого значения остаётся неизменным.
Типовая модель:
dateFormatter(options) →
(date: Date) => stringСтрогая типизация обеспечивается следующими правилами:
Date;Дополнительно важно, что временные зоны и локальные представления не влияют на тип, только на содержимое строки.
Message formatter представляет собой более сложный типовой случай, так как он включает интерполяцию, plural-правила и выбор ветвления.
Формально:
objectstringОднако внутри системы происходит дополнительная типизация параметров:
string | number | Date.Таким образом формируется полиморфный входной контракт:
TParams = Record<string, string | number | Date>Несмотря на это, итоговый тип результата остаётся фиксированным:
stringЭто обеспечивает совместимость с любыми локализациями сообщений без изменения сигнатуры функции.
В TypeScript-интеграциях Globalize типизация форматтеров описывается через обобщённые интерфейсы, однако сама библиотека не навязывает строгие compile-time ограничения.
Типовая модель:
Это создаёт гибридную систему:
Кастомные форматтеры расширяют систему типов через обобщённые интерфейсы функций:
(value: T) => stringПри этом тип T зависит от доменной области:
numberstringobjectГлавное ограничение заключается в унификации результата:
string.Это позволяет сохранять совместимость с системой message formatting и цепочками локализации.
Типизация форматтеров строится на нескольких инвариантах:
Эти свойства обеспечивают предсказуемость поведения в условиях интернационализации.
Форматтеры могут использоваться в композиции, где результат одного становится входом другого. При этом типовая модель сохраняет следующее правило:
string.Таким образом цепочка форматирования выглядит типово однородной:
Отсутствие промежуточных нетипизированных структур снижает риск несоответствия типов в сложных локализационных сценариях.
Типовая система форматтеров не является полной в смысле статической проверки:
В результате типизация описывает только верхний уровень:
Внутренняя семантика локализации остаётся динамической.