Библиотека date-fns изначально проектировалась с ориентацией на строгую типизацию, что делает её удобной для использования в TypeScript-проектах без дополнительных обёрток и деклараций типов. Каждая функция экспортирует явно описанные сигнатуры, что позволяет компилятору выводить корректные типы на основании входных аргументов.
Типовая сигнатура большинства функций выглядит предсказуемо:
function addDays(date: Date | number, amount: number): Date
Первый аргумент почти всегда допускает Date | number,
где число интерпретируется как timestamp (миллисекунды Unix-времени).
Возвращаемое значение — новый экземпляр Date, что
подчёркивает неизменяемость операций.
Ключевая особенность — отсутствие мутирующих операций. Типы это отражают: исходные данные не изменяются, результат всегда возвращается отдельно.
TypeScript-совместимость обеспечивается через унифицированный подход к входным параметрам. Практически все функции принимают:
Datenumber (timestamp)string (в ограниченных парсинг-функциях)Пример типизированного использования:
import { format, addMonths } from "date-fns";
const start: Date = new Date(2024, 0, 1);
const result: Date = addMonths(start, 3);
const label: string = format(result, "yyyy-MM-dd");
Компилятор фиксирует корректность типов на уровне вызова функций. Ошибочные конструкции, например передача объектов или строк в арифметические функции, приводят к ошибкам компиляции.
Многие функции date-fns используют перегрузки для обеспечения гибкости без потери типовой безопасности.
Пример:
declare function parse(
dateString: string,
formatString: string,
referenceDate: Date
): Date;
declare function parse(
dateString: string,
formatString: string,
referenceDate: number
): Date;
Перегрузки позволяют корректно обрабатывать разные типы referenceDate, сохраняя единый возвращаемый тип.
TypeScript выбирает нужную сигнатуру автоматически, основываясь на переданных аргументах.
В date-fns активно используются опциональные параметры, особенно в функциях форматирования и локализации.
import { format } from "date-fns";
import { ru } from "date-fns/locale";
const d: Date = new Date();
const s1: string = format(d, "PP");
const s2: string = format(d, "PP", { locale: ru });
Тип опций описывается через интерфейсы:
interface FormatOptions {
locale?: Locale;
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
firstWeekContainsDate?: number;
}
Строгая типизация ограничивает допустимые значения, например для
weekStartsOn используется union-тип.
date-fns полностью поддерживает ES Modules и TypeScript module resolution.
Типы встроены в пакет, поэтому отдельная установка
@types/date-fns не требуется.
Пример структуры импортов:
import { addDays, differenceInDays } from "date-fns";
Tree-shaking сохраняется, поскольку каждый модуль экспортируется отдельно. TypeScript корректно анализирует такие импорты и не включает лишний код в сборку.
Локали в date-fns представляют собой строго типизированные объекты
Locale.
import { Locale } from "date-fns";
import { enUS, de, ru } from "date-fns/locale";
const locale: Locale = ru;
Тип Locale включает:
Типизация предотвращает передачу некорректных объектов локалей, например частичных или самодельных структур без полного контракта.
date-fns предоставляет функциональный API в стиле FP через подмодуль
date-fns/fp. Он отличается каррированием функций и
изменённым порядком аргументов.
import { addDays, format } from "date-fns/fp";
const addTenDays = addDays(10);
const result: string = format("yyyy-MM-dd", addTenDays(new Date()));
Типизация FP-версии строится через обобщённые функции высшего порядка:
type CurriedAddDays = (amount: number) => (date: Date) => Date;
Такая модель позволяет использовать композицию функций без потери типовой информации.
TypeScript в связке с date-fns обычно используется в режиме
strict: true, что усиливает контроль типов.
Функции date-fns не принимают null или
undefined в качестве валидных дат:
addDays(null as any, 5); // потенциальная ошибка типизации
В строгом режиме подобные конструкции блокируются на этапе компиляции.
Для обработки неопределённых значений применяется явная нормализация:
const safeDate: Date = inputDate ?? new Date();
const updated: Date = addDays(safeDate, 7);
Функции парсинга возвращают Date, но не выполняют
автоматическую валидацию на уровне типов, что отражается в
контракте:
function parseISO(argument: string): Date;
TypeScript не различает корректные и некорректные даты на уровне
типов, поэтому результат всегда остаётся Date, даже если он
может быть невалидным (Invalid Date).
Для этого применяется вспомогательная проверка:
import { isValid } from "date-fns";
const d: Date = parseISO("2024-13-40");
const ok: boolean = isValid(d);
Тип boolean отделяет этап проверки от этапа
использования значения.
Некоторые внутренние механизмы date-fns используют generics для сохранения информации о типах входных параметров:
type DateArg<DateType extends Date = Date> = DateType | number;
Это позволяет сохранять совместимость с расширенными типами даты в
пользовательских обёртках или альтернативных реализациях
Date.
Работа с диапазонами дат использует строго описанные структуры:
interface Interval {
start: Date | number;
end: Date | number;
}
Функции, работающие с интервалами, принимают только этот контракт:
import { isWithinInterval } from "date-fns";
const interval: Interval = {
start: new Date(2024, 0, 1),
end: new Date(2024, 11, 31),
};
const result: boolean = isWithinInterval(new Date(), interval);
Типизация гарантирует наличие обоих полей, исключая частично определённые структуры.
date-fns не конфликтует с DOM-типами TypeScript. Использование
Date из стандартной библиотеки обеспечивает единый контракт
между браузером и Node.js.
Функции форматирования и вычислений не зависят от окружения, что сохраняет идентичность типов в разных средах исполнения.
При комбинировании функций TypeScript корректно выводит промежуточные типы:
import { addDays, format } from "date-fns";
const transform = (d: Date): string =>
format(addDays(d, 5), "yyyy-MM-dd");
Тип вывода определяется как:
DateDatestringПри сложных композициях это позволяет сохранять прозрачность типового потока без дополнительных аннотаций.
date-fns не моделирует ошибки через исключения в типах. Все функции остаются чистыми с точки зрения сигнатур:
throws в TypeScript декларацияхResult<T, E> типовInvalid Date, false)Такой подход упрощает интеграцию с существующими типовыми системами TypeScript и снижает необходимость обработки исключений на уровне типов.