Параметр validationError.target

Общее назначение свойства target

ValidationError.target представляет собой исходный объект, который подвергался валидации. Это одно из ключевых полей структуры ValidationError, возвращаемой функцией validate() или validateSync().

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

Свойство имеет следующую семантику:

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

Тип данных и структура

target обычно имеет тип object, соответствующий валидируемому классу или plain object.

Пример базовой структуры ValidationError:

interface ValidationError {
  target?: object;
  property: string;
  value: any;
  constraints?: {
    [type: string]: string;
  };
  children?: ValidationError[];
}

target присутствует только в корневых ошибках. В дочерних элементах (children) оно часто отсутствует или не дублируется для экономии памяти и предотвращения избыточного копирования.


Поведение при простой валидации

При валидации плоского объекта target содержит полный входной объект:

import { validate } from "class-validator";

class User {
  name: string;
}

const user = new User();
user.name = null;

validate(user).then(errors => {
  console.log(errors[0].target);
});

Результатом будет:

User { name: null }

target указывает на исходный экземпляр User, даже если ошибки связаны только с одним свойством.


Поведение при вложенных структурах

При сложных объектах с вложенными классами target фиксирует верхнеуровневый объект, а вложенные ошибки переходят в children.

class Address {
  street: string;
}

class User {
  address: Address;
}

При ошибке внутри address.street:

  • target верхнего уровня указывает на User
  • вложенный ValidationError содержит children, но не всегда дублирует target

Пример структуры:

{
  target: User { address: Address {} },
  property: "address",
  children: [
    {
      property: "street",
      value: undefined,
      constraints: { isNotEmpty: "street should not be empty" }
    }
  ]
}

Влияние параметров validate() на target

Поведение target зависит от опций валидации.

skipMissingProperties

Опция не удаляет target, но может уменьшить количество ошибок, где он появляется.

validate(user, { skipMissingProperties: true });

target остаётся ссылкой на исходный объект, даже если часть полей пропущена.


whitelist

При включении whitelist: true свойства, не имеющие декораторов, удаляются из объекта.

Это влияет на содержимое target:

validate(user, { whitelist: true });

В этом случае:

  • target может быть уже модифицированным объектом
  • отсутствующие свойства физически удаляются
  • диагностика становится зависимой от финальной формы объекта

forbidNonWhitelisted

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

validate(user, { whitelist: true, forbidNonWhitelisted: true });

ошибки могут включать target, в котором уже отсутствуют неразрешённые поля. Это важно учитывать при логировании, так как исходное состояние частично теряется.


Отличие target от value

ValidationError.value и ValidationError.target часто путаются, однако они выполняют разные функции:

  • target — весь объект валидации
  • value — конкретное значение свойства, вызвавшего ошибку

Пример:

{
  target: User { name: "A", age: 10 },
  property: "age",
  value: 10
}

target сохраняет контекст всего объекта, тогда как value локализует проблему.


Поведение при трансформациях class-transformer

При использовании вместе с трансформацией объектов (например, через plainToInstance) target может отражать уже преобразованную структуру:

const user = plainToInstance(User, plainObject);
validate(user);

В этом случае:

  • target = экземпляр класса User
  • исходный plain object уже не представлен напрямую
  • изменения типов (string → number) отражаются в target

Глубокая валидация и наследование target

При использовании вложенных классов и декораторов:

  • target фиксируется только на уровне корневого объекта
  • дочерние ошибки наследуют контекст через children
  • повторное копирование target не выполняется

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


Практическое значение для диагностики

target используется в следующих сценариях:

  • логирование ошибок валидации
  • построение debug-отчётов
  • трассировка входных данных API
  • анализ причин некорректных значений
  • интеграция с логирующими системами

Типичный паттерн логирования:

validate(dto).then(errors => {
  errors.forEach(err => {
    console.log(err.target, err.property, err.constraints);
  });
});

Особенности сериализации

При попытке сериализовать ValidationError:

JSON.stringify(errors)

target может:

  • быть урезанным (циклические ссылки)
  • терять методы класса
  • превращаться в plain object

Это связано с тем, что target может содержать экземпляры классов с прототипами.


Ограничения и побочные эффекты

Использование target связано с рядом особенностей:

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

Эти факторы делают target диагностическим, а не строго стабильным полем.


Связь с архитектурой ValidationError

target является частью внутреннего механизма трассировки ошибок:

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

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