Skip to content

Validation: refactor and improve typing - #34649

Merged
pharret31 merged 6 commits into
DevExpress:mainfrom
pharret31:3837-validation-refactor-and-improve-typing
Aug 5, 2026
Merged

Validation: refactor and improve typing#34649
pharret31 merged 6 commits into
DevExpress:mainfrom
pharret31:3837-validation-refactor-and-improve-typing

Conversation

@pharret31

Copy link
Copy Markdown
Contributor

No description provided.

@pharret31 pharret31 self-assigned this Aug 4, 2026
Copilot AI review requested due to automatic review settings August 4, 2026 14:50
@pharret31
pharret31 requested a review from a team as a code owner August 4, 2026 14:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on improving TypeScript typing and internal type-safety across the DevExtreme validation subsystem (validator, validation engine, validation summary/message/group), including aligning runtime expectations in tests.

Changes:

  • Introduced/expanded internal validation types (ValidationResultInternal, ValidationRuleInternal, adapter/editor structural types) and propagated them through validator/engine/summary/message/group.
  • Refactored several internal validation components to remove legacy inheritance/@ts-expect-error patterns and replace iterator utilities with native constructs.
  • Updated a QUnit test expectation for brokenRule to be undefined on valid validation results.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validator.tests.js Updates expectation for brokenRule value in onValidated params.
packages/devextreme/js/__internal/ui/validation/m_default_adapter.ts Adds typed editor/adapter structural contracts and narrows adapter behavior typings.
packages/devextreme/js/__internal/ui/m_validator.ts Tightens internal validator typings and refactors validation rule/result handling.
packages/devextreme/js/__internal/ui/m_validation_summary.ts Types validation summary items/results and refactors ordering and item update logic.
packages/devextreme/js/__internal/ui/m_validation_message.ts Narrows/overrides several option types and strengthens internal typing of positioning/message rendering.
packages/devextreme/js/__internal/ui/m_validation_group.ts Improves typing for validation group component and instance retrieval.
packages/devextreme/js/__internal/ui/m_validation_engine.ts Introduces internal validation types and refactors rule validation loop and async handling.
packages/devextreme/js/__internal/integration/knockout/validation.ts Aligns KO validator handling with updated validation result typing/async flow.
Suppressed comments (1)

packages/devextreme/js/__internal/ui/m_validation_engine.ts:803

  • This return true causes the surrounding .some() call to stop at the first failing rule, so later rules are not evaluated/added to brokenRules. Validation results are expected to include all broken rules (see tests in validationEngine.tests.js asserting 2–3 broken rules).
      if (!rule.isValid) {
        return true;
      }

Comment thread packages/devextreme/js/__internal/ui/m_validation_engine.ts
Copilot AI review requested due to automatic review settings August 4, 2026 16:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (3)

packages/devextreme/js/__internal/ui/validation/m_default_adapter.ts:18

  • ValidationTargetEditorOptions.validationError is typed as ValidationRuleInternal, but editors can set validationError to an editor-specific object without a type field (e.g. number box sets { editorSpecific: true, message: ... }). This makes the adapter/validator typings overly strict and inconsistent with actual runtime values. Consider introducing a dedicated internal type for validation errors (e.g. EditorValidationErrorInternal) and using it for validationError(s)/brokenRule(s) across the adapter, validator, and validation engine types.
export interface ValidationTargetEditorOptions {
  value?: unknown;
  validationError?: ValidationRuleInternal | null;
  disabled?: boolean;
  rtlEnabled?: boolean;
}

packages/devextreme/js/__internal/ui/m_validation_engine.ts:85

  • ValidationResultInternal.brokenRule/brokenRules are typed as ValidationRuleInternal, but validator code can populate them from editor-specific validationError objects that don't have a type (e.g. { editorSpecific: true, message: ... }). This makes result typing misleading and can lead to incorrect assumptions about the shape of brokenRules in downstream code. Consider widening the broken-rule type (e.g. a union of ValidationRuleInternal and an EditorValidationErrorInternal shape that includes message, editorSpecific, validator, index).
export interface ValidationResultInternal {
  name?: string;
  value?: unknown;
  brokenRule?: ValidationRuleInternal | null;
  brokenRules?: ValidationRuleInternal[] | null;
  isValid?: boolean;

packages/devextreme/js/__internal/ui/m_validation_message.ts:34

  • validationErrors can include editor-specific error objects (and is also typed as Record<string, unknown>[] in existing wrappers), so ValidationRuleInternal[] is too narrow here. Widen the element type to avoid incorrectly implying every error has a validation rule type.
  validationErrors?: ValidationRuleInternal[] | null;

@pharret31 pharret31 changed the title typing of validation Validation: refactor and improve typing Aug 4, 2026
Copilot AI review requested due to automatic review settings August 5, 2026 08:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.

Suppressed comments (13)

packages/devextreme/js/ui/validation_engine.js:1

  • These public js/ui/*.js entry points consistently import implementation via relative ../__internal/... paths (e.g. packages/devextreme/js/ui/button.js:1). Introducing the @ts/* alias here is inconsistent with the rest of the folder and may rely on alias resolution for plain .js sources. Consider switching back to a relative ../__internal/... import.
import ValidationEngine from '@ts/ui/validation_engine';

packages/devextreme/js/ui/validator.js:1

  • These public js/ui/*.js entry points consistently import implementation via relative ../__internal/... paths (e.g. packages/devextreme/js/ui/button.js:1). Introducing the @ts/* alias here is inconsistent with the rest of the folder and may rely on alias resolution for plain .js sources. Consider switching back to a relative ../__internal/... import.
import Validator from '@ts/ui/validator';

packages/devextreme/js/ui/validation_group.js:1

  • These public js/ui/*.js entry points consistently import implementation via relative ../__internal/... paths (e.g. packages/devextreme/js/ui/button.js:1). Introducing the @ts/* alias here is inconsistent with the rest of the folder and may rely on alias resolution for plain .js sources. Consider switching back to a relative ../__internal/... import.
import ValidationGroup from '@ts/ui/validation_group';

packages/devextreme/js/ui/validation_message.js:1

  • These public js/ui/*.js entry points consistently import implementation via relative ../__internal/... paths (e.g. packages/devextreme/js/ui/button.js:1). Introducing the @ts/* alias here is inconsistent with the rest of the folder and may rely on alias resolution for plain .js sources. Consider switching back to a relative ../__internal/... import.
import ValidationMessage from '@ts/ui/validation_message';

packages/devextreme/testing/tests/DevExpress.ui.widgets/button.tests.js:5

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validator.tests.js:4

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validator.editors.tests.js:4

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/js/ui/validation_summary.js:1

  • These public js/ui/*.js entry points consistently import implementation via relative ../__internal/... paths (e.g. packages/devextreme/js/ui/button.js:1). Introducing the @ts/* alias here is inconsistent with the rest of the folder and may rely on alias resolution for plain .js sources. Consider switching back to a relative ../__internal/... import.
import ValidationSummary from '@ts/ui/validation_summary';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validationSummary.tests.js:3

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validationSummary.markup.tests.js:3

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validationGroup.tests.js:5

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/validationGroup.markup.tests.js:3

  • Most QUnit tests import internal implementation modules via the __internal/* alias (e.g. packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/treeList.tests.js:4). Using @ts/* in plain .js tests is inconsistent with that pattern; consider switching to the equivalent __internal/... import for the new adapter module.
import DefaultAdapter from '@ts/ui/validation/default_adapter';

packages/devextreme/js/__internal/ui/validation/default_adapter.ts:24

  • ValidationTargetEditor is documented as either an Editor or an R1 wrapper (which uses the standard option(name) getter, e.g. packages/devextreme/js/__internal/ui/check_box/editor_base/wrapper.ts:29). The ValidationTargetEditorOption overloads currently omit the getter signature, making the structural type incomplete.
interface ValidationTargetEditorOption {
  (): ValidationTargetEditorOptions;
  (name: string, value: unknown): void;
  (options: Record<string, unknown>): void;
}

Copilot AI review requested due to automatic review settings August 5, 2026 08:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 5, 2026 08:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/devextreme/js/__internal/ui/validation_group.ts:9

  • This file imports ValidationEngine/Validator/ValidationSummary via relative paths, while the rest of the refactor consistently uses the @ts/ui/* aliases (e.g. validator.ts, validation_summary.ts). Mixing import specifiers for a stateful singleton like ValidationEngine risks creating multiple module instances (separate groups state) depending on bundler/module resolution, and is also inconsistent with nearby code.
    packages/devextreme/js/__internal/ui/validation_engine.ts:35
  • The named import list from @js/core/utils/type has isNumeric, isObject on the same line, which is inconsistent with the surrounding one-per-line formatting in this import block and makes future diffs noisier.
  isDefined,
  isFunction,
  isNumeric, isObject,
  isPromise,

@pharret31
pharret31 added this pull request to the merge queue Aug 5, 2026
Merged via the queue into DevExpress:main with commit dafacef Aug 5, 2026
101 checks passed
@pharret31
pharret31 deleted the 3837-validation-refactor-and-improve-typing branch August 5, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants