Интеграция с strict mode

Библиотека date-fns ориентирована на функциональный подход и предсказуемую работу с датами. При использовании strict mode в JavaScript код становится более безопасным, а многие потенциальные ошибки выявляются ещё на этапе разработки.

Strict mode ("use strict") влияет не только на синтаксис языка, но и на способы взаимодействия с функциями, импортами и объектами Date. В сочетании с date-fns это позволяет добиться:

  • более строгой проверки аргументов;
  • отсутствия скрытых преобразований;
  • безопасной работы с модулями;
  • корректного tree-shaking;
  • лучшей совместимости с TypeScript и современными сборщиками.

Включение strict mode

Strict mode активируется директивой:

"use strict";

Пример:

"use strict";

import { format } from "date-fns";

const result = format(new Date(), "yyyy-MM-dd");

console.log(result);

В ECMAScript-модулях (ESM) strict mode включается автоматически:

import { addDays } from "date-fns";

const tomorrow = addDays(new Date(), 1);

Дополнительная директива уже не требуется.


Поведение date-fns в strict mode

Отсутствие зависимости от this

Одно из важных преимуществ date-fns — отсутствие привязки к контексту this.

Во многих старых библиотеках методы дат вызывались через объект:

moment().add(1, "day");

В strict mode неправильный контекст может приводить к ошибкам:

someMethod(); // this === undefined

В date-fns все функции являются чистыми:

import { addDays } from "date-fns";

const result = addDays(new Date(), 5);

Контекст не используется вообще, поэтому strict mode не создаёт дополнительных проблем.


Ошибки неявных глобальных переменных

Strict mode запрещает создание глобальных переменных без let, const или var.

Неправильный код:

"use strict";

currentDate = new Date();

Ошибка:

ReferenceError: currentDate is not defined

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

"use strict";

const currentDate = new Date();

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


Импорт функций в strict mode

Именованные импорты

date-fns построена вокруг модульной архитектуры.

Корректный импорт:

import { format, parseISO } from "date-fns";

Strict mode предотвращает некоторые ошибки переопределения импортированных сущностей.

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

"use strict";

import { format } from "date-fns";

format = null;

Ошибка:

TypeError: Assignment to constant variable

Импортированные функции являются неизменяемыми ссылками.


Работа с CommonJS

В проектах на Node.js можно встретить CommonJS:

"use strict";

const { format } = require("date-fns");

Strict mode здесь особенно полезен, так как старые CommonJS-модули часто содержали небезопасные конструкции.


Защита от мутации объектов Date

Проблема изменяемости Date

Объект Date в JavaScript изменяемый:

const date = new Date();

date.setHours(15);

Это может приводить к трудноуловимым ошибкам.

Подход date-fns

Большинство функций date-fns возвращают новый объект даты:

import { addHours } from "date-fns";

const original = new Date();
const updated = addHours(original, 2);

console.log(original);
console.log(updated);

Strict mode усиливает безопасность такого подхода, особенно в функциональной архитектуре приложения.


Использование immutable-подхода

Нежелательный подход

"use strict";

const date = new Date();

function updateDate(d) {
  d.setDate(d.getDate() + 1);
}

updateDate(date);

Функция изменяет исходный объект.

Предпочтительный подход с date-fns

"use strict";

import { addDays } from "date-fns";

const date = new Date();
const nextDay = addDays(date, 1);

Исходное значение остаётся неизменным.


Проверка аргументов

Strict mode не проверяет типы аргументов автоматически, однако делает ошибки более очевидными.

Пример неправильного вызова:

"use strict";

import { addDays } from "date-fns";

addDays(undefined, 5);

Результат:

Invalid Date

Корректная практика — предварительная валидация.


Проверка валидности даты

Функция isValid помогает безопасно работать с датами.

import { isValid } from "date-fns";

const date = new Date("invalid");

console.log(isValid(date));

Результат:

false

В strict mode подобные проверки особенно важны, поскольку код становится менее терпимым к ошибкам.


Безопасный парсинг дат

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

import { parseISO } from "date-fns";

const date = parseISO("2025-10-15");

Проверка результата

import { parseISO, isValid } from "date-fns";

const parsed = parseISO("wrong-value");

if (!isValid(parsed)) {
  throw new Error("Некорректная дата");
}

Strict mode хорошо сочетается с таким defensive programming-подходом.


Работа с функциями высшего порядка

date-fns часто используется вместе с map, filter, reduce.

Пример:

"use strict";

import { format } from "date-fns";

const dates = [
  new Date(2025, 0, 1),
  new Date(2025, 0, 2),
  new Date(2025, 0, 3)
];

const formatted = dates.map(date =>
  format(date, "yyyy-MM-dd")
);

console.log(formatted);

Strict mode предотвращает случайные ошибки внутри callback-функций.


Использование стрелочных функций

Strict mode меняет поведение this в обычных функциях:

"use strict";

function test() {
  console.log(this);
}

test();

Результат:

undefined

Поскольку date-fns не использует this, библиотека особенно хорошо сочетается со стрелочными функциями:

const normalize = dates =>
  dates.map(date => startOfDay(date));

Интеграция с TypeScript

Автоматический strict mode

В TypeScript strict mode часто включается через:

{
  "compilerOptions": {
    "strict": true
  }
}

date-fns предоставляет качественные типы, благодаря чему ошибки обнаруживаются ещё до выполнения кода.


Проверка nullable-значений

Потенциально опасный код

import { format } from "date-fns";

function printDate(date?: Date) {
  return format(date, "yyyy-MM-dd");
}

Ошибка TypeScript:

Argument of type 'Date | undefined'
is not assignable to parameter of type 'Date | number'

Безопасный вариант

import { format } from "date-fns";

function printDate(date?: Date) {
  if (!date) {
    return "Дата отсутствует";
  }

  return format(date, "yyyy-MM-dd");
}

noImplicitAny и date-fns

При включённом noImplicitAny необходимо явно задавать типы:

import { addDays } from "date-fns";

function shift(date: Date, amount: number): Date {
  return addDays(date, amount);
}

Это делает API обработки дат значительно надёжнее.


strictNullChecks

Одна из наиболее полезных возможностей strict mode в TypeScript.

import { parseISO } from "date-fns";

function parse(value: string | null) {
  return parseISO(value);
}

Ошибка:

Argument of type 'string | null'
is not assignable to parameter of type 'string'

Безопасный вариант:

function parse(value: string | null) {
  if (value === null) {
    return null;
  }

  return parseISO(value);
}

Работа со временем в асинхронном коде

Strict mode помогает избегать скрытых ошибок в таймерах и асинхронных операциях.

Пример:

"use strict";

import { differenceInSeconds } from "date-fns";

async function measure() {
  const start = new Date();

  await fetch("/api/data");

  const end = new Date();

  return differenceInSeconds(end, start);
}

Использование date-fns в React

В React strict mode включается через:

<React.StrictMode>
  <App />
</React.StrictMode>

date-fns хорошо подходит для React благодаря:

  • отсутствию побочных эффектов;
  • immutable-подходу;
  • чистым функциям;
  • отсутствию внутреннего состояния.

Пример:

import { format } from "date-fns";

function DateLabel({ date }) {
  return (
    <span>
      {format(date, "dd.MM.yyyy")}
    </span>
  );
}

Повторный рендеринг в React Strict Mode

В режиме разработки React может дважды вызывать функции компонентов.

date-fns безопасна в таком сценарии:

const formatted = format(new Date(), "HH:mm:ss");

Функция не изменяет внешнее состояние и не вызывает side effects.


Tree-shaking и strict mode

date-fns проектировалась с учётом tree-shaking.

Правильный импорт:

import { format } from "date-fns";

Неправильный импорт:

import * as dateFns from "date-fns";

В strict mode и современных сборщиках (Vite, Webpack, Rollup) использование именованных импортов позволяет минимизировать размер итогового bundle.


Ошибки duplicate parameter names

Strict mode запрещает дублирование параметров:

"use strict";

function formatDate(date, date) {
  return date;
}

Ошибка:

SyntaxError

Это особенно полезно при написании собственных обёрток над date-fns.


Безопасная работа с часовыми поясами

При использовании функций вроде:

import { formatISO } from "date-fns";

важно избегать неявных преобразований.

Нежелательный код:

const value = "2025-10-10";
const date = new Date(value);

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

Предпочтительно:

import { parseISO } from "date-fns";

const date = parseISO("2025-10-10");

Обработка исключений

Использование try/catch

"use strict";

import { parse } from "date-fns";

try {
  const result = parse(
    "2025-15-99",
    "yyyy-MM-dd",
    new Date()
  );

  console.log(result);
} catch (error) {
  console.error(error);
}

Strict mode делает стек ошибок более предсказуемым.


Создание собственных утилит

Пример безопасной обёртки

"use strict";

import { format, isValid } from "date-fns";

export function safeFormat(date, pattern) {
  if (!isValid(date)) {
    return "";
  }

  return format(date, pattern);
}

Использование Object.freeze

В strict mode попытка изменить frozen-объект вызывает ошибку.

"use strict";

const config = Object.freeze({
  pattern: "yyyy-MM-dd"
});

config.pattern = "dd.MM.yyyy";

Результат:

TypeError

Это полезно при хранении конфигурации форматирования date-fns.


Интеграция с ESLint

Strict mode обычно используется совместно с линтерами.

Полезные правила:

{
  "rules": {
    "no-undef": "error",
    "no-global-assign": "error",
    "no-param-reassign": "error"
  }
}

В сочетании с date-fns это помогает поддерживать функциональный стиль кода.


Создание безопасных helper-функций

"use strict";

import {
  startOfMonth,
  endOfMonth
} from "date-fns";

export function getMonthRange(date) {
  return {
    start: startOfMonth(date),
    end: endOfMonth(date)
  };
}

Функция:

  • не изменяет входные данные;
  • не зависит от глобального состояния;
  • безопасна для strict mode;
  • легко тестируется.

Тестирование в strict mode

При написании unit-тестов strict mode позволяет быстрее выявлять ошибки.

Пример:

"use strict";

import { addDays } from "date-fns";

test("adds one day", () => {
  const result = addDays(
    new Date(2025, 0, 1),
    1
  );

  expect(result.getDate()).toBe(2);
});

Архитектурные преимущества

Интеграция date-fns со strict mode формирует устойчивую архитектуру обработки дат:

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