Типы date-fns

Библиотека date-fns построена вокруг стандартного объекта Date из JavaScript и не вводит собственный класс даты. Основная идея — работа с нативными значениями времени через чистые функции. В TypeScript библиотека предоставляет набор типов, дженериков и вспомогательных интерфейсов, обеспечивающих строгую типизацию операций с датами.


Основной тип Date

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

Date

Пример:

import { addDays } from 'date-fns'

const date = new Date()

const result = addDays(date, 5)

Тип результата:

Date

Большинство функций принимают:

Date | number | string

Однако в TypeScript официально используется более строгая модель.


Тип DateArg

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

Условно его можно представить так:

type DateArg<DateType extends Date> =
  | DateType
  | number
  | string

Он позволяет функциям принимать:

  • объект Date
  • timestamp
  • строку даты

Пример:

parseISO('2025-01-10')
fromUnixTime(1700000000)
new Date()

Дженерики в date-fns

Одной из важных особенностей новых версий библиотеки стала поддержка пользовательских типов даты через дженерики.

Типичная сигнатура функции:

function addDays<
  DateType extends Date,
  ResultDate extends Date = DateType
>(
  date: DateArg<DateType>,
  amount: number,
  options?: AddDaysOptions<ResultDate>
): ResultDate

Здесь:

  • DateType — тип входящей даты
  • ResultDate — тип возвращаемого значения

Зачем нужны дженерики

Дженерики позволяют использовать расширенные классы дат.

Например:

class UTCDate extends Date {
  isUTC = true
}

Теперь функции способны сохранять тип:

const utcDate = new UTCDate()

const result = addDays(utcDate, 3)

Тип результата:

UTCDate

Без дженериков был бы потерян пользовательский тип, а результатом стал обычный Date.


Тип Interval

Многие функции работают с интервалами времени.

Для этого используется тип:

Interval

Структура:

interface Interval {
  start: Date
  end: Date
}

Пример:

import { eachDayOfInterval } from 'date-fns'

const interval = {
  start: new Date(2025, 0, 1),
  end: new Date(2025, 0, 5),
}

const days = eachDayOfInterval(interval)

Тип Duration

Тип Duration описывает длительность времени.

Структура:

interface Duration {
  years?: number
  months?: number
  weeks?: number
  days?: number
  hours?: number
  minutes?: number
  seconds?: number
}

Пример:

import { add } from 'date-fns'

const result = add(new Date(), {
  days: 5,
  hours: 2,
})

Здесь объект соответствует типу Duration.


Частичные Duration-объекты

Все поля в Duration необязательны.

Допустимы конструкции:

{
  days: 10
}

или:

{
  minutes: 30
}

Это делает API гибким и удобным.


Тип Locale

Для локализации используется тип:

Locale

Он описывает набор правил форматирования:

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

Пример:

import { format } from 'date-fns'
import { ru } from 'date-fns/locale'

format(new Date(), 'PPPP', {
  locale: ru,
})

Тип ru:

Locale

Структура Locale

Тип Locale достаточно большой.

Упрощённо:

interface Locale {
  code?: string
  formatDistance: Function
  formatRelative: Function
  localize: Object
  formatLong: Object
  match: Object
  options?: Object
}

Тип WeekOptions

Некоторые функции поддерживают настройки недели.

Используется тип:

WeekOptions

Пример:

startOfWeek(date, {
  weekStartsOn: 1,
})

Здесь:

weekStartsOn: number

означает день начала недели.


Тип FirstWeekContainsDateOptions

Для ISO-логики календаря используется:

FirstWeekContainsDateOptions

Пример:

getWeek(date, {
  firstWeekContainsDate: 4,
})

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


Комбинированные option-типы

Многие функции используют композицию типов.

Например:

interface WeekOptions {
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6
}

и:

interface FirstWeekContainsDateOptions {
  firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}

Позже они объединяются:

type WeekStartOptions &
FirstWeekContainsDateOptions

Тип FormatOptions

Функция format использует большой набор настроек.

Пример:

format(date, 'yyyy-MM-dd', {
  locale: ru,
  useAdditionalWeekYearTokens: true,
})

Тип параметров:

FormatOptions

Тип ParseOptions

Для функции parse используется:

ParseOptions

Пример:

parse(
  '2025-01-10',
  'yyyy-MM-dd',
  new Date(),
  {
    locale: ru,
  }
)

Тип StrictValidationMap

Во внутренней реализации парсинга используются специальные карты валидации токенов.

Они контролируют:

  • допустимость форматов
  • совместимость токенов
  • строгий режим парсинга

Пример несовместимых токенов:

HH a

Поскольку:

  • HH — 24-часовой формат
  • a — AM/PM

Тип Matcher

В системе локализации используется тип:

Matcher

Он отвечает за распознавание строк:

январь
понедельник
вчера

и преобразование их в значения даты.


Тип LocalizeFn

Локализация формируется через специальные функции.

Пример:

type LocalizeFn<Value> = (
  value: Value,
  options?: LocalizeOptions
) => string

Используется для:

  • месяцев
  • дней недели
  • кварталов
  • эпох

Тип Era

Внутренний тип эпох:

type Era = 0 | 1

Обычно:

0 -> BC
1 -> AD

Тип Quarter

Тип квартала:

type Quarter = 1 | 2 | 3 | 4

Используется в:

setQuarter()
getQuarter()

Тип Month

Тип месяца:

type Month =
  | 0
  | 1
  | 2
  | 3
  | 4
  | 5
  | 6
  | 7
  | 8
  | 9
  | 10
  | 11

Соответствует JavaScript API.


Тип Day

Тип дня недели:

type Day =
  | 0
  | 1
  | 2
  | 3
  | 4
  | 5
  | 6

Тип NearestMinutesOptions

Используется функцией:

roundToNearestMinutes()

Пример:

roundToNearestMinutes(date, {
  nearestTo: 15,
})

Тип:

interface NearestMinutesOptions {
  nearestTo?: number
  roundingMethod?: string
}

Тип RoundingMethod

Некоторые функции поддерживают методы округления.

Пример:

differenceInHours(a, b, {
  roundingMethod: 'ceil',
})

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

'ceil'
'floor'
'round'
'trunc'

Тип IntervalToDurationOptions

Используется функцией:

intervalToDuration()

Позволяет задавать настройки вычисления длительности.


Тип FormatDistanceOptions

Функция:

formatDistance()

использует:

FormatDistanceOptions

Пример:

formatDistance(date1, date2, {
  addSuffix: true,
})

Тип FormatRelativeOptions

Для:

formatRelative()

используется:

FormatRelativeOptions

Тип ISOStringFormatOptions

Некоторые функции ISO-форматирования поддерживают:

representation: 'complete'
representation: 'date'
representation: 'time'

Это часть типа:

ISOStringFormatOptions

Тип AdditionalTokensOptions

Date-fns строго контролирует использование токенов форматирования.

Тип:

AdditionalTokensOptions

содержит:

useAdditionalWeekYearTokens
useAdditionalDayOfYearTokens

Тип ContextOptions

В новых версиях библиотеки появился контекст выполнения операций с датами.

Тип:

ContextOptions

используется для передачи дополнительной среды обработки даты.


Тип ISOWeekOptions

Некоторые функции поддерживают ISO-недели.

Пример:

getISOWeek()
startOfISOWeek()

Связанные типы:

ISOWeekOptions

Nullable-типы в date-fns

Большинство функций не принимают null и undefined.

Например:

addDays(null, 5)

приведёт к ошибке типизации.

Это принципиальное отличие от многих старых библиотек.


Invalid Date и типизация

Тип Date не гарантирует корректность даты.

Пример:

const date = new Date('wrong')

Тип:

Date

Но значение:

Invalid Date

Для проверки используется:

isValid(date)

Типизация parseISO

Функция:

parseISO()

всегда возвращает:

Date

Даже если строка невалидна.

Пример:

const result = parseISO('abc')

Результат:

Invalid Date

Типизация compare-функций

Функции:

compareAsc()
compareDesc()

возвращают:

number

Возможные значения:

-1
0
1

Типизация difference-функций

Функции:

differenceInDays()
differenceInMonths()

возвращают:

number

Типизация predicate-функций

Функции-предикаты возвращают:

boolean

Примеры:

isAfter()
isBefore()
isEqual()
isWeekend()

Типизация массивов дат

Функции генерации диапазонов возвращают:

Date[]

Пример:

const days = eachDayOfInterval({
  start,
  end,
})

Типизация set-функций

Функции изменения компонентов даты:

setYear()
setMonth()
setDate()

возвращают новый объект:

Date

Исходная дата не мутируется.


Иммутабельность и типы

Все функции библиотеки являются чистыми.

Пример:

const original = new Date()

const modified = addDays(original, 5)

Типы:

original -> Date
modified -> Date

При этом:

original !== modified

Типизация FP-модуля

В модуле:

date-fns/fp

используется каррирование.

Пример:

import { addDays } from 'date-fns/fp'

const addFiveDays = addDays(5)

Тип функции:

(date: Date) => Date

Типизация pipe-композиций

Благодаря строгой типизации FP-версии хорошо работают с:

  • pipe
  • flow
  • функциональными композициями

Пример:

const processDate =
  flow(
    addDays(5),
    startOfMonth,
    endOfWeek
  )

Типизация UTCDate

Некоторые экосистемные расширения используют:

UTCDate
TZDate

Date-fns сохраняет совместимость благодаря дженерикам.


Типизация пользовательских классов даты

Пример:

class CustomDate extends Date {
  timezone = 'UTC'
}

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

const result = addHours(
  new CustomDate(),
  5
)

Результат сохраняет тип:

CustomDate

Проблемы типизации строковых дат

Хотя JavaScript допускает:

new Date('2025-01-01')

строковые даты часто приводят к:

  • timezone-проблемам
  • platform-specific parsing
  • невалидным форматам

Поэтому date-fns рекомендует:

parseISO()

Строгая типизация токенов format

Начиная с современных версий библиотеки токены:

YYYY
DD

считаются небезопасными.

Правильные варианты:

yyyy
dd

Типы и проверки помогают избежать ошибок миграции с Moment.js.


Типизация Unix Timestamp

Timestamp представлен типом:

number

Пример:

fromUnixTime(1700000000)

или:

getTime()

Типизация milliseconds

Многие функции работают именно с миллисекундами.

Например:

addMilliseconds()
differenceInMilliseconds()

Все значения:

number

Типизация временных зон

Базовая библиотека не содержит полноценного типа timezone.

Для этого используются дополнительные пакеты:

  • date-fns-tz
  • @date-fns/utc

Типизация date-fns-tz

В расширении временных зон используются строковые идентификаторы:

'Asia/Almaty'
'Europe/Berlin'
'UTC'

Тип:

string

Особенности типизации formatDistance

Функции расстояния между датами активно используют union-типы.

Например:

'lessThanXSeconds'
'xMinutes'
'aboutXHours'

Это позволяет локалям строго контролировать шаблоны текста.


Внутренние utility-типы

Во внутреннем коде библиотеки используются:

Nullable<T>
DefaultOptions
LocalizedOptions

Они помогают строить гибкую архитектуру API.


Типизация глобальных настроек

Date-fns поддерживает глобальные default options:

setDefaultOptions({
  weekStartsOn: 1,
})

Тип параметра:

DefaultOptions

Типизация parseJSON

Функция:

parseJSON()

возвращает:

Date

и поддерживает:

  • ISO строки
  • JSON timestamp
  • UTC форматы

Типизация interval-функций

Функции:

isWithinInterval()
clamp()

используют:

Interval

Пример:

isWithinInterval(date, {
  start,
  end,
})

Типизация strict options

Некоторые API поддерживают строгие union-типы.

Например:

roundingMethod:
  | 'ceil'
  | 'floor'
  | 'round'
  | 'trunc'

Это исключает передачу произвольных строк.


Роль типов в архитектуре date-fns

Типизация библиотеки построена вокруг нескольких принципов:

  • совместимость с нативным Date
  • отсутствие мутаций
  • поддержка расширяемости
  • строгие union-типы
  • безопасность форматирования
  • поддержка TypeScript без сторонних деклараций
  • сохранение пользовательских типов через дженерики

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