@angular/forms 21.0.0-next.8 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.8
2
+ * @license Angular v21.0.0-rc.0
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -7,26 +7,60 @@
7
7
  import { HttpResourceRequest, HttpResourceOptions } from '@angular/common/http';
8
8
  import * as i0 from '@angular/core';
9
9
  import { InjectionToken, ɵControl as _Control, ɵCONTROL as _CONTROL, ɵFieldState as _FieldState, Signal, ResourceRef, InputSignal, ModelSignal, OutputRef, WritableSignal, DestroyableInjector, Injector } from '@angular/core';
10
+ import { NgControl, AbstractControl, ValidationErrors, FormControlStatus, ControlValueAccessor, ValidatorFn } from '@angular/forms';
10
11
  import { StandardSchemaV1 } from '@standard-schema/spec';
11
12
 
13
+ /**
14
+ * Properties of both NgControl & AbstractControl that are supported by the InteropNgControl.
15
+ */
16
+ type InteropSharedKeys = 'value' | 'valid' | 'invalid' | 'touched' | 'untouched' | 'disabled' | 'enabled' | 'errors' | 'pristine' | 'dirty' | 'status';
17
+ /**
18
+ * A fake version of `NgControl` provided by the `Field` directive. This allows interoperability
19
+ * with a wider range of components designed to work with reactive forms, in particular ones that
20
+ * inject the `NgControl`. The interop control does not implement *all* properties and methods of
21
+ * the real `NgControl`, but does implement some of the most commonly used ones that have a clear
22
+ * equivalent in signal forms.
23
+ */
24
+ declare class InteropNgControl implements Pick<NgControl, InteropSharedKeys | 'control' | 'valueAccessor'>, Pick<AbstractControl<unknown>, InteropSharedKeys | 'hasValidator'> {
25
+ protected field: () => FieldState<unknown>;
26
+ constructor(field: () => FieldState<unknown>);
27
+ readonly control: AbstractControl<any, any>;
28
+ get value(): any;
29
+ get valid(): boolean;
30
+ get invalid(): boolean;
31
+ get pending(): boolean | null;
32
+ get disabled(): boolean;
33
+ get enabled(): boolean;
34
+ get errors(): ValidationErrors | null;
35
+ get pristine(): boolean;
36
+ get dirty(): boolean;
37
+ get touched(): boolean;
38
+ get untouched(): boolean;
39
+ get status(): FormControlStatus;
40
+ valueAccessor: ControlValueAccessor | null;
41
+ hasValidator(validator: ValidatorFn): boolean;
42
+ updateValueAndValidity(): void;
43
+ }
44
+
12
45
  /**
13
46
  * Lightweight DI token provided by the {@link Field} directive.
47
+ *
48
+ * @category control
49
+ * @experimental 21.0.0
14
50
  */
15
51
  declare const FIELD: InjectionToken<Field<unknown>>;
16
52
  /**
17
53
  * Binds a form `FieldTree` to a UI control that edits it. A UI control can be one of several things:
18
54
  * 1. A native HTML input or textarea
19
55
  * 2. A signal forms custom control that implements `FormValueControl` or `FormCheckboxControl`
20
- * 3. TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131712274. A
21
- * component that provides a ControlValueAccessor. This should only be used to backwards
56
+ * 3. A component that provides a `ControlValueAccessor`. This should only be used for backwards
22
57
  * compatibility with reactive forms. Prefer options (1) and (2).
23
58
  *
24
59
  * This directive has several responsibilities:
25
60
  * 1. Two-way binds the field's value with the UI control's value
26
61
  * 2. Binds additional forms related state on the field to the UI control (disabled, required, etc.)
27
62
  * 3. Relays relevant events on the control to the field (e.g. marks field touched on blur)
28
- * 4. TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131712274.
29
- * Provides a fake `NgControl` that implements a subset of the features available on the
63
+ * 4. Provides a fake `NgControl` that implements a subset of the features available on the
30
64
  * reactive forms `NgControl`. This is provided to improve interoperability with controls
31
65
  * designed to work with reactive forms. It should not be used by controls written for signal
32
66
  * forms.
@@ -39,125 +73,138 @@ declare class Field<T> implements _Control<T> {
39
73
  readonly field: i0.InputSignal<FieldTree<T>>;
40
74
  readonly state: i0.Signal<FieldState<T, string | number>>;
41
75
  readonly [_CONTROL]: undefined;
42
- register(): void;
76
+ /** Any `ControlValueAccessor` instances provided on the host element. */
77
+ private readonly controlValueAccessors;
78
+ /** A lazily instantiated fake `NgControl`. */
79
+ private interopNgControl;
80
+ /** A `ControlValueAccessor`, if configured, for the host component. */
81
+ private get controlValueAccessor();
82
+ get ɵhasInteropControl(): boolean;
83
+ /** Lazily instantiates a fake `NgControl` for this field. */
84
+ ɵgetOrCreateNgControl(): InteropNgControl;
85
+ ɵinteropControlCreate(): void;
86
+ ɵinteropControlUpdate(): void;
87
+ ɵregister(): void;
43
88
  static ɵfac: i0.ɵɵFactoryDeclaration<Field<any>, never>;
44
89
  static ɵdir: i0.ɵɵDirectiveDeclaration<Field<any>, "[field]", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
45
90
  }
46
91
 
47
92
  /**
48
- * Represents a property that may be defined on a field when it is created using a `property` rule
49
- * in the schema. A particular `Property` can only be defined on a particular field **once**.
93
+ * Represents metadata that may be defined on a field when it is created using a `metadata` rule
94
+ * in the schema. A particular `MetadataKey` can only be defined on a particular field **once**.
50
95
  *
51
96
  * @category logic
52
97
  * @experimental 21.0.0
53
98
  */
54
- declare class Property<TValue> {
99
+ declare class MetadataKey<TValue> {
55
100
  private brand;
56
- /** Use {@link createProperty}. */
101
+ /** Use {@link createMetadataKey}. */
57
102
  private constructor();
58
103
  }
59
104
  /**
60
- * Creates a {@link Property}.
105
+ * Creates a {@link MetadataKey}.
61
106
  *
62
107
  * @experimental 21.0.0
63
108
  */
64
- declare function createProperty<TValue>(): Property<TValue>;
109
+ declare function createMetadataKey<TValue>(): MetadataKey<TValue>;
65
110
  /**
66
- * Represents a property that is aggregated from multiple parts according to the property's reducer
111
+ * Represents metadata that is aggregated from multiple parts according to the key's reducer
67
112
  * function. A value can be contributed to the aggregated value for a field using an
68
- * `aggregateProperty` rule in the schema. There may be multiple rules in a schema that contribute
69
- * values to the same `AggregateProperty` of the same field.
113
+ * `aggregateMetadata` rule in the schema. There may be multiple rules in a schema that contribute
114
+ * values to the same `AggregateMetadataKey` of the same field.
70
115
  *
71
116
  * @experimental 21.0.0
72
117
  */
73
- declare class AggregateProperty<TAcc, TItem> {
118
+ declare class AggregateMetadataKey<TAcc, TItem> {
74
119
  readonly reduce: (acc: TAcc, item: TItem) => TAcc;
75
120
  readonly getInitial: () => TAcc;
76
121
  private brand;
77
- /** Use {@link reducedProperty}. */
122
+ /** Use {@link reducedMetadataKey}. */
78
123
  private constructor();
79
124
  }
80
125
  /**
81
- * Creates an aggregate property that reduces its individual values into an accumulated value using
82
- * the given `reduce` and `getInitial` functions.
126
+ * Creates an {@link AggregateMetadataKey} that reduces its individual values into an accumulated
127
+ * value using the given `reduce` and `getInitial` functions.
83
128
  * @param reduce The reducer function.
84
129
  * @param getInitial A function that gets the initial value for the reduce operation.
85
130
  *
86
131
  * @experimental 21.0.0
87
132
  */
88
- declare function reducedProperty<TAcc, TItem>(reduce: (acc: TAcc, item: TItem) => TAcc, getInitial: () => TAcc): AggregateProperty<TAcc, TItem>;
133
+ declare function reducedMetadataKey<TAcc, TItem>(reduce: (acc: TAcc, item: TItem) => TAcc, getInitial: () => TAcc): AggregateMetadataKey<TAcc, TItem>;
89
134
  /**
90
- * Creates an aggregate property that reduces its individual values into a list.
135
+ * Creates an {@link AggregateMetadataKey} that reduces its individual values into a list.
91
136
  *
92
137
  * @experimental 21.0.0
93
138
  */
94
- declare function listProperty<TItem>(): AggregateProperty<TItem[], TItem | undefined>;
139
+ declare function listMetadataKey<TItem>(): AggregateMetadataKey<TItem[], TItem | undefined>;
95
140
  /**
96
- * Creates an aggregate property that reduces its individual values by taking their min.
141
+ * Creates {@link AggregateMetadataKey} that reduces its individual values by taking their min.
97
142
  *
98
143
  * @experimental 21.0.0
99
144
  */
100
- declare function minProperty(): AggregateProperty<number | undefined, number | undefined>;
145
+ declare function minMetadataKey(): AggregateMetadataKey<number | undefined, number | undefined>;
101
146
  /**
102
- * Creates an aggregate property that reduces its individual values by taking their max.
147
+ * Creates {@link AggregateMetadataKey} that reduces its individual values by taking their max.
103
148
  *
104
149
  * @experimental 21.0.0
105
150
  */
106
- declare function maxProperty(): AggregateProperty<number | undefined, number | undefined>;
151
+ declare function maxMetadataKey(): AggregateMetadataKey<number | undefined, number | undefined>;
107
152
  /**
108
- * Creates an aggregate property that reduces its individual values by logically or-ing them.
153
+ * Creates an {@link AggregateMetadataKey} that reduces its individual values by logically or-ing
154
+ * them.
109
155
  *
110
156
  * @experimental 21.0.0
111
157
  */
112
- declare function orProperty(): AggregateProperty<boolean, boolean>;
158
+ declare function orMetadataKey(): AggregateMetadataKey<boolean, boolean>;
113
159
  /**
114
- * Creates an aggregate property that reduces its individual values by logically and-ing them.
160
+ * Creates an {@link AggregateMetadataKey} that reduces its individual values by logically and-ing
161
+ * them.
115
162
  *
116
163
  * @experimental 21.0.0
117
164
  */
118
- declare function andProperty(): AggregateProperty<boolean, boolean>;
165
+ declare function andMetadataKey(): AggregateMetadataKey<boolean, boolean>;
119
166
  /**
120
- * An aggregate property representing whether the field is required.
167
+ * An {@link AggregateMetadataKey} representing whether the field is required.
121
168
  *
122
169
  * @category validation
123
170
  * @experimental 21.0.0
124
171
  */
125
- declare const REQUIRED: AggregateProperty<boolean, boolean>;
172
+ declare const REQUIRED: AggregateMetadataKey<boolean, boolean>;
126
173
  /**
127
- * An aggregate property representing the min value of the field.
174
+ * An {@link AggregateMetadataKey} representing the min value of the field.
128
175
  *
129
176
  * @category validation
130
177
  * @experimental 21.0.0
131
178
  */
132
- declare const MIN: AggregateProperty<number | undefined, number | undefined>;
179
+ declare const MIN: AggregateMetadataKey<number | undefined, number | undefined>;
133
180
  /**
134
- * An aggregate property representing the max value of the field.
181
+ * An {@link AggregateMetadataKey} representing the max value of the field.
135
182
  *
136
183
  * @category validation
137
184
  * @experimental 21.0.0
138
185
  */
139
- declare const MAX: AggregateProperty<number | undefined, number | undefined>;
186
+ declare const MAX: AggregateMetadataKey<number | undefined, number | undefined>;
140
187
  /**
141
- * An aggregate property representing the min length of the field.
188
+ * An {@link AggregateMetadataKey} representing the min length of the field.
142
189
  *
143
190
  * @category validation
144
191
  * @experimental 21.0.0
145
192
  */
146
- declare const MIN_LENGTH: AggregateProperty<number | undefined, number | undefined>;
193
+ declare const MIN_LENGTH: AggregateMetadataKey<number | undefined, number | undefined>;
147
194
  /**
148
- * An aggregate property representing the max length of the field.
195
+ * An {@link AggregateMetadataKey} representing the max length of the field.
149
196
  *
150
197
  * @category validation
151
198
  * @experimental 21.0.0
152
199
  */
153
- declare const MAX_LENGTH: AggregateProperty<number | undefined, number | undefined>;
200
+ declare const MAX_LENGTH: AggregateMetadataKey<number | undefined, number | undefined>;
154
201
  /**
155
- * An aggregate property representing the patterns the field must match.
202
+ * An {@link AggregateMetadataKey} representing the patterns the field must match.
156
203
  *
157
204
  * @category validation
158
205
  * @experimental 21.0.0
159
206
  */
160
- declare const PATTERN: AggregateProperty<RegExp[], RegExp | undefined>;
207
+ declare const PATTERN: AggregateMetadataKey<RegExp[], RegExp | undefined>;
161
208
 
162
209
  /**
163
210
  * Options used to create a `ValidationError`.
@@ -339,7 +386,7 @@ declare function standardSchemaError(issue: StandardSchemaV1.Issue, options?: Va
339
386
  * @category validation
340
387
  * @experimental 21.0.0
341
388
  */
342
- declare function customError<E extends Partial<ValidationError>>(obj: WithField<E>): CustomValidationError;
389
+ declare function customError<E extends Partial<ValidationErrorWithField>>(obj: WithField<E>): CustomValidationError;
343
390
  /**
344
391
  * Create a custom error
345
392
  * @param obj The object to create an error from
@@ -347,11 +394,14 @@ declare function customError<E extends Partial<ValidationError>>(obj: WithField<
347
394
  * @category validation
348
395
  * @experimental 21.0.0
349
396
  */
350
- declare function customError<E extends Partial<ValidationError>>(obj?: E): WithoutField<CustomValidationError>;
397
+ declare function customError<E extends Partial<ValidationErrorWithField>>(obj?: E): WithoutField<CustomValidationError>;
351
398
  /**
352
399
  * Common interface for all validation errors.
353
400
  *
354
- * Use the creation functions to create an instance (e.g. `requiredError`, `minError`, etc.).
401
+ * This can be returned from validators.
402
+ *
403
+ * It's also used by the creation functions to create an instance
404
+ * (e.g. `requiredError`, `minError`, etc.).
355
405
  *
356
406
  * @category validation
357
407
  * @experimental 21.0.0
@@ -359,11 +409,38 @@ declare function customError<E extends Partial<ValidationError>>(obj?: E): Witho
359
409
  interface ValidationError {
360
410
  /** Identifies the kind of error. */
361
411
  readonly kind: string;
362
- /** The field associated with this error. */
363
- readonly field: FieldTree<unknown>;
364
412
  /** Human readable error message. */
365
413
  readonly message?: string;
366
414
  }
415
+ /**
416
+ * Validation error with a field.
417
+ *
418
+ * This is returned from field state, e.g., catField.errors() would be of a list of errors with
419
+ * `field: catField` bound to state.
420
+ */
421
+ interface ValidationErrorWithField extends ValidationError {
422
+ /** The field associated with this error. */
423
+ readonly field: FieldTree<unknown>;
424
+ }
425
+ /**
426
+ * Validation error with optional field.
427
+ *
428
+ * This is generally used in places where the result might have a field.
429
+ * e.g., as a result of a `validateTree`, or when handling form submission.
430
+ */
431
+ interface ValidationErrorWithOptionalField extends ValidationError {
432
+ /** The field associated with this error. */
433
+ readonly field?: FieldTree<unknown>;
434
+ }
435
+ /**
436
+ * Validation error with no field.
437
+ *
438
+ * This is used to strongly enforce that fields are not allowed in validation result.
439
+ */
440
+ interface ValidationErrorWithoutField extends ValidationError {
441
+ /** The field associated with this error. */
442
+ readonly field?: never;
443
+ }
367
444
  /**
368
445
  * A custom error that may contain additional properties
369
446
  *
@@ -518,15 +595,6 @@ type NgValidationError = RequiredValidationError | MinValidationError | MaxValid
518
595
  * Symbol used to retain generic type information when it would otherwise be lost.
519
596
  */
520
597
  declare const ɵɵTYPE: unique symbol;
521
- /**
522
- * Creates a type based on the given type T, but with all readonly properties made writable.
523
- * @template T The type to create a mutable version of.
524
- *
525
- * @experimental 21.0.0
526
- */
527
- type Mutable<T> = {
528
- -readonly [P in keyof T]: T[P];
529
- };
530
598
  /**
531
599
  * A type that represents either a single value of type `T` or a readonly array of `T`.
532
600
  * @template T The type of the value(s).
@@ -591,21 +659,6 @@ interface DisabledReason {
591
659
  * @experimental 21.0.0
592
660
  */
593
661
  type ValidationSuccess = null | undefined | void;
594
- /**
595
- * The result of running a field validation function.
596
- *
597
- * The result may be one of the following:
598
- * 1. A {@link ValidationSuccess} to indicate no errors.
599
- * 2. A {@link ValidationError} without a field to indicate an error on the field being validated.
600
- * 3. A list of {@link ValidationError} without fields to indicate multiple errors on the field
601
- * being validated.
602
- *
603
- * @template E the type of error (defaults to {@link ValidationError}).
604
- *
605
- * @category types
606
- * @experimental 21.0.0
607
- */
608
- type FieldValidationResult<E extends ValidationError = ValidationError> = ValidationSuccess | OneOrMany<WithoutField<E>>;
609
662
  /**
610
663
  * The result of running a tree validation function.
611
664
  *
@@ -620,7 +673,7 @@ type FieldValidationResult<E extends ValidationError = ValidationError> = Valida
620
673
  * @category types
621
674
  * @experimental 21.0.0
622
675
  */
623
- type TreeValidationResult<E extends ValidationError = ValidationError> = ValidationSuccess | OneOrMany<WithOptionalField<E>>;
676
+ type TreeValidationResult<E extends ValidationErrorWithOptionalField = ValidationErrorWithOptionalField> = ValidationSuccess | OneOrMany<E>;
624
677
  /**
625
678
  * A validation result where all errors explicitly define their target field.
626
679
  *
@@ -719,11 +772,11 @@ interface FieldState<TValue, TKey extends string | number = string | number> ext
719
772
  */
720
773
  readonly hidden: Signal<boolean>;
721
774
  readonly disabledReasons: Signal<readonly DisabledReason[]>;
722
- readonly errors: Signal<ValidationError[]>;
775
+ readonly errors: Signal<ValidationErrorWithField[]>;
723
776
  /**
724
777
  * A signal containing the {@link errors} of the field and its descendants.
725
778
  */
726
- readonly errorSummary: Signal<ValidationError[]>;
779
+ readonly errorSummary: Signal<ValidationErrorWithField[]>;
727
780
  /**
728
781
  * A signal indicating whether the field's value is currently valid.
729
782
  *
@@ -766,19 +819,19 @@ interface FieldState<TValue, TKey extends string | number = string | number> ext
766
819
  */
767
820
  readonly fieldBindings: Signal<readonly Field<unknown>[]>;
768
821
  /**
769
- * Reads an aggregate property value from the field.
770
- * @param prop The property to read.
822
+ * Reads an aggregate metadata value from the field.
823
+ * @param key The metadata key to read.
771
824
  */
772
- property<M>(prop: AggregateProperty<M, any>): Signal<M>;
825
+ metadata<M>(key: AggregateMetadataKey<M, any>): Signal<M>;
773
826
  /**
774
- * Reads a property value from the field.
775
- * @param prop The property key to read.
827
+ * Reads a metadata value from the field.
828
+ * @param key The metadata key to read.
776
829
  */
777
- property<M>(prop: Property<M>): M | undefined;
830
+ metadata<M>(key: MetadataKey<M>): M | undefined;
778
831
  /**
779
832
  * Checks whether the given metadata key has been defined for this field.
780
833
  */
781
- hasProperty(key: Property<any> | AggregateProperty<any, any>): boolean;
834
+ hasMetadata(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean;
782
835
  /**
783
836
  * Resets the {@link touched} and {@link dirty} state of the field and its descendants.
784
837
  *
@@ -868,7 +921,7 @@ type LogicFn<TValue, TReturn, TPathKind extends PathKind = PathKind.Root> = (ctx
868
921
  * @category validation
869
922
  * @experimental 21.0.0
870
923
  */
871
- type FieldValidator<TValue, TPathKind extends PathKind = PathKind.Root> = LogicFn<TValue, FieldValidationResult, TPathKind>;
924
+ type FieldValidator<TValue, TPathKind extends PathKind = PathKind.Root> = LogicFn<TValue, ValidationResult<ValidationErrorWithoutField>, TPathKind>;
872
925
  /**
873
926
  * A function that takes the `FieldContext` for the field being validated and returns a
874
927
  * `TreeValidationResult` indicating errors for the field and its sub-fields.
@@ -985,6 +1038,11 @@ interface AsyncValidatorOptions<TValue, TParams, TResult, TPathKind extends Path
985
1038
  * @returns A reference to the constructed resource.
986
1039
  */
987
1040
  readonly factory: (params: Signal<TParams | undefined>) => ResourceRef<TResult | undefined>;
1041
+ /**
1042
+ * A function to handle errors thrown by httpResource (HTTP errors, network errors, etc.).
1043
+ * Receives the error and the field context, returns a list of validation errors.
1044
+ */
1045
+ readonly onError: (error: unknown, ctx: FieldContext<TValue, TPathKind>) => TreeValidationResult;
988
1046
  /**
989
1047
  * A function that takes the resource result, and the current field context and maps it to a list
990
1048
  * of validation errors.
@@ -996,7 +1054,7 @@ interface AsyncValidatorOptions<TValue, TParams, TResult, TPathKind extends Path
996
1054
  * A targeted error will show up as an error on its target field rather than the field being validated.
997
1055
  * If a field is not given, the error is assumed to apply to the field being validated.
998
1056
  */
999
- readonly errors: MapToErrorsFn<TValue, TResult, TPathKind>;
1057
+ readonly onSuccess: MapToErrorsFn<TValue, TResult, TPathKind>;
1000
1058
  }
1001
1059
  /**
1002
1060
  * Options that indicate how to create an httpResource for async validation for a field,
@@ -1029,7 +1087,12 @@ interface HttpValidatorOptions<TValue, TResult, TPathKind extends PathKind = Pat
1029
1087
  * A targeted error will show up as an error on its target field rather than the field being validated.
1030
1088
  * If a field is not given, the error is assumed to apply to the field being validated.
1031
1089
  */
1032
- readonly errors: MapToErrorsFn<TValue, TResult, TPathKind>;
1090
+ readonly onSuccess: MapToErrorsFn<TValue, TResult, TPathKind>;
1091
+ /**
1092
+ * A function to handle errors thrown by httpResource (HTTP errors, network errors, etc.).
1093
+ * Receives the error and the field context, returns a list of validation errors.
1094
+ */
1095
+ readonly onError: (error: unknown, ctx: FieldContext<TValue, TPathKind>) => TreeValidationResult;
1033
1096
  /**
1034
1097
  * The options to use when creating the httpResource.
1035
1098
  */
@@ -1278,44 +1341,44 @@ declare function validate<TValue, TPathKind extends PathKind = PathKind.Root>(pa
1278
1341
  */
1279
1342
  declare function validateTree<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic: NoInfer<TreeValidator<TValue, TPathKind>>): void;
1280
1343
  /**
1281
- * Adds a value to an `AggregateProperty` of a field.
1344
+ * Adds a value to an {@link AggregateMetadataKey} of a field.
1282
1345
  *
1283
- * @param path The target path to set the aggregate property on.
1284
- * @param prop The aggregate property
1285
- * @param logic A function that receives the `FieldContext` and returns a value to add to the aggregate property.
1346
+ * @param path The target path to set the aggregate metadata on.
1347
+ * @param key The aggregate metadata key
1348
+ * @param logic A function that receives the `FieldContext` and returns a value to add to the aggregate metadata.
1286
1349
  * @template TValue The type of value stored in the field the logic is bound to.
1287
- * @template TPropItem The type of value the property aggregates over.
1350
+ * @template TMetadataItem The type of value the metadata aggregates over.
1288
1351
  * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1289
1352
  *
1290
1353
  * @category logic
1291
1354
  * @experimental 21.0.0
1292
1355
  */
1293
- declare function aggregateProperty<TValue, TPropItem, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, prop: AggregateProperty<any, TPropItem>, logic: NoInfer<LogicFn<TValue, TPropItem, TPathKind>>): void;
1356
+ declare function aggregateMetadata<TValue, TMetadataItem, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, key: AggregateMetadataKey<any, TMetadataItem>, logic: NoInfer<LogicFn<TValue, TMetadataItem, TPathKind>>): void;
1294
1357
  /**
1295
- * Creates a new `Property` and defines the value of the new property for the given field.
1358
+ * Creates a new {@link MetadataKey} and defines the value of the new metadata key for the given field.
1296
1359
  *
1297
- * @param path The path to define the property for.
1298
- * @param factory A factory function that creates the value for the property.
1360
+ * @param path The path to define the metadata for.
1361
+ * @param factory A factory function that creates the value for the metadata.
1299
1362
  * This function is **not** reactive. It is run once when the field is created.
1300
- * @returns The newly created property
1363
+ * @returns The newly created metadata key
1301
1364
  *
1302
1365
  * @category logic
1303
1366
  * @experimental 21.0.0
1304
1367
  */
1305
- declare function property<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): Property<TData>;
1368
+ declare function metadata<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): MetadataKey<TData>;
1306
1369
  /**
1307
- * Defines the value of a `Property` for a given field.
1370
+ * Defines the value of a {@link MetadataKey} for a given field.
1308
1371
  *
1309
- * @param path The path to define the property for.
1310
- * @param prop The property to define.
1311
- * @param factory A factory function that creates the value for the property.
1372
+ * @param path The path to define the metadata for.
1373
+ * @param key The metadata key to define.
1374
+ * @param factory A factory function that creates the value for the metadata.
1312
1375
  * This function is **not** reactive. It is run once when the field is created.
1313
- * @returns The given property
1376
+ * @returns The given metadata key
1314
1377
  *
1315
1378
  * @category logic
1316
1379
  * @experimental 21.0.0
1317
1380
  */
1318
- declare function property<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, prop: Property<TData>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): Property<TData>;
1381
+ declare function metadata<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, key: MetadataKey<TData>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): MetadataKey<TData>;
1319
1382
 
1320
1383
  /** Represents a result that should be ignored because its predicate indicates it is not active. */
1321
1384
  declare const IGNORED: unique symbol;
@@ -1429,46 +1492,46 @@ declare class LogicContainer {
1429
1492
  /** Logic that determines if the field is read-only. */
1430
1493
  readonly readonly: BooleanOrLogic;
1431
1494
  /** Logic that produces synchronous validation errors for the field. */
1432
- readonly syncErrors: ArrayMergeIgnoreLogic<ValidationError, null>;
1495
+ readonly syncErrors: ArrayMergeIgnoreLogic<ValidationErrorWithField, null>;
1433
1496
  /** Logic that produces synchronous validation errors for the field's subtree. */
1434
- readonly syncTreeErrors: ArrayMergeIgnoreLogic<ValidationError, null>;
1497
+ readonly syncTreeErrors: ArrayMergeIgnoreLogic<ValidationErrorWithField, null>;
1435
1498
  /** Logic that produces asynchronous validation results (errors or 'pending'). */
1436
- readonly asyncErrors: ArrayMergeIgnoreLogic<ValidationError | 'pending', null>;
1437
- /** A map of aggregate properties to the `AbstractLogic` instances that compute their values. */
1438
- private readonly aggregateProperties;
1439
- /** A map of property keys to the factory functions that create their values. */
1440
- private readonly propertyFactories;
1499
+ readonly asyncErrors: ArrayMergeIgnoreLogic<ValidationErrorWithField | 'pending', null>;
1500
+ /** A map of aggregate metadata keys to the `AbstractLogic` instances that compute their values. */
1501
+ private readonly aggregateMetadataKeys;
1502
+ /** A map of metadata keys to the factory functions that create their values. */
1503
+ private readonly metadataFactories;
1441
1504
  /**
1442
1505
  * Constructs a new `Logic` container.
1443
1506
  * @param predicates An array of predicates that must all be true for the logic
1444
1507
  * functions within this container to be active.
1445
1508
  */
1446
1509
  constructor(predicates: ReadonlyArray<BoundPredicate>);
1447
- /** Checks whether there is logic for the given aggregate property. */
1448
- hasAggregateProperty(prop: AggregateProperty<unknown, unknown>): boolean;
1510
+ /** Checks whether there is logic for the given aggregate metadata key. */
1511
+ hasAggregateMetadata(key: AggregateMetadataKey<any, any>): boolean;
1449
1512
  /**
1450
- * Gets an iterable of [aggregate property, logic function] pairs.
1451
- * @returns An iterable of aggregate property entries.
1513
+ * Gets an iterable of [aggregate metadata, logic function] pairs.
1514
+ * @returns An iterable of aggregate metadata entries.
1452
1515
  */
1453
- getAggregatePropertyEntries(): MapIterator<[AggregateProperty<unknown, unknown>, AbstractLogic<unknown, unknown>]>;
1516
+ getAggregateMetadataEntries(): MapIterator<[AggregateMetadataKey<unknown, unknown>, AbstractLogic<unknown, unknown>]>;
1454
1517
  /**
1455
- * Gets an iterable of [property, value factory function] pairs.
1456
- * @returns An iterable of property factory entries.
1518
+ * Gets an iterable of [metadata, value factory function] pairs.
1519
+ * @returns An iterable of metadata factory entries.
1457
1520
  */
1458
- getPropertyFactoryEntries(): MapIterator<[Property<unknown>, (ctx: FieldContext<unknown>) => unknown]>;
1521
+ getMetadataFactoryEntries(): MapIterator<[MetadataKey<unknown>, (ctx: FieldContext<unknown>) => unknown]>;
1459
1522
  /**
1460
- * Retrieves or creates the `AbstractLogic` for a given aggregate property.
1461
- * @param prop The `AggregateProperty` for which to get the logic.
1523
+ * Retrieves or creates the `AbstractLogic` for a given aggregate metadata key.
1524
+ * @param key The `AggregateMetadataKey` for which to get the logic.
1462
1525
  * @returns The `AbstractLogic` associated with the key.
1463
1526
  */
1464
- getAggregateProperty<T>(prop: AggregateProperty<unknown, T>): AbstractLogic<T>;
1527
+ getAggregateMetadata<T>(key: AggregateMetadataKey<unknown, T>): AbstractLogic<T>;
1465
1528
  /**
1466
- * Adds a factory function for a given property.
1467
- * @param prop The `Property` to associate the factory with.
1529
+ * Adds a factory function for a given metadata key.
1530
+ * @param key The `MetadataKey` to associate the factory with.
1468
1531
  * @param factory The factory function.
1469
1532
  * @throws If a factory is already defined for the given key.
1470
1533
  */
1471
- addPropertyFactory(prop: Property<unknown>, factory: (ctx: FieldContext<unknown>) => unknown): void;
1534
+ addMetadataFactory(key: MetadataKey<unknown>, factory: (ctx: FieldContext<unknown>) => unknown): void;
1472
1535
  /**
1473
1536
  * Merges logic from another `Logic` instance into this one.
1474
1537
  * @param other The `Logic` instance to merge from.
@@ -1500,10 +1563,10 @@ declare abstract class AbstractLogicNodeBuilder {
1500
1563
  abstract addSyncTreeErrorRule(logic: LogicFn<any, ValidationResult>): void;
1501
1564
  /** Adds a rule for asynchronous validation errors for a field. */
1502
1565
  abstract addAsyncErrorRule(logic: LogicFn<any, AsyncValidationResult>): void;
1503
- /** Adds a rule to compute an aggregate property for a field. */
1504
- abstract addAggregatePropertyRule<M>(key: AggregateProperty<unknown, M>, logic: LogicFn<any, M>): void;
1566
+ /** Adds a rule to compute aggregate metadata for a field. */
1567
+ abstract addAggregateMetadataRule<M>(key: AggregateMetadataKey<unknown, M>, logic: LogicFn<any, M>): void;
1505
1568
  /** Adds a factory function to produce a data value associated with a field. */
1506
- abstract addPropertyFactory<D>(key: Property<D>, factory: (ctx: FieldContext<any>) => D): void;
1569
+ abstract addMetadataFactory<D>(key: MetadataKey<D>, factory: (ctx: FieldContext<any>) => D): void;
1507
1570
  /**
1508
1571
  * Gets a builder for a child node associated with the given property key.
1509
1572
  * @param key The property key of the child.
@@ -1546,11 +1609,11 @@ declare class LogicNodeBuilder extends AbstractLogicNodeBuilder {
1546
1609
  addHiddenRule(logic: LogicFn<any, boolean>): void;
1547
1610
  addDisabledReasonRule(logic: LogicFn<any, DisabledReason | undefined>): void;
1548
1611
  addReadonlyRule(logic: LogicFn<any, boolean>): void;
1549
- addSyncErrorRule(logic: LogicFn<any, ValidationResult>): void;
1550
- addSyncTreeErrorRule(logic: LogicFn<any, ValidationResult>): void;
1551
- addAsyncErrorRule(logic: LogicFn<any, AsyncValidationResult>): void;
1552
- addAggregatePropertyRule<T>(key: AggregateProperty<unknown, T>, logic: LogicFn<any, T>): void;
1553
- addPropertyFactory<D>(key: Property<D>, factory: (ctx: FieldContext<any>) => D): void;
1612
+ addSyncErrorRule(logic: LogicFn<any, ValidationResult<ValidationErrorWithField>>): void;
1613
+ addSyncTreeErrorRule(logic: LogicFn<any, ValidationResult<ValidationErrorWithField>>): void;
1614
+ addAsyncErrorRule(logic: LogicFn<any, AsyncValidationResult<ValidationErrorWithField>>): void;
1615
+ addAggregateMetadataRule<T>(key: AggregateMetadataKey<unknown, T>, logic: LogicFn<any, T>): void;
1616
+ addMetadataFactory<D>(key: MetadataKey<D>, factory: (ctx: FieldContext<any>) => D): void;
1554
1617
  getChild(key: PropertyKey): LogicNodeBuilder;
1555
1618
  hasLogic(builder: AbstractLogicNodeBuilder): boolean;
1556
1619
  /**
@@ -1628,8 +1691,10 @@ declare class SchemaImpl {
1628
1691
  declare class FieldPathNode {
1629
1692
  /** The property keys used to navigate from the root path to this path. */
1630
1693
  readonly keys: PropertyKey[];
1631
- /** The logic builder used to accumulate logic on this path node. */
1632
- readonly logic: LogicNodeBuilder;
1694
+ /** The parent of this path node. */
1695
+ private readonly parent;
1696
+ /** The key of this node in its parent. */
1697
+ private readonly keyInParent;
1633
1698
  /** The root path node from which this path node is descended. */
1634
1699
  readonly root: FieldPathNode;
1635
1700
  /**
@@ -1641,11 +1706,20 @@ declare class FieldPathNode {
1641
1706
  * A proxy that wraps the path node, allowing navigation to its child paths via property access.
1642
1707
  */
1643
1708
  readonly fieldPathProxy: FieldPath<any>;
1709
+ /**
1710
+ * For a root path node this will contain the root logic builder. For non-root nodes,
1711
+ * they determine their logic builder from their parent so this is undefined.
1712
+ */
1713
+ private readonly logicBuilder;
1644
1714
  protected constructor(
1645
1715
  /** The property keys used to navigate from the root path to this path. */
1646
- keys: PropertyKey[],
1716
+ keys: PropertyKey[], root: FieldPathNode | undefined,
1717
+ /** The parent of this path node. */
1718
+ parent: FieldPathNode | undefined,
1719
+ /** The key of this node in its parent. */
1720
+ keyInParent: PropertyKey | undefined);
1647
1721
  /** The logic builder used to accumulate logic on this path node. */
1648
- logic: LogicNodeBuilder, root: FieldPathNode);
1722
+ get builder(): LogicNodeBuilder;
1649
1723
  /**
1650
1724
  * Gets the special path node containing the per-element logic that applies to *all* children paths.
1651
1725
  */
@@ -1668,21 +1742,17 @@ declare class FieldPathNode {
1668
1742
  }
1669
1743
 
1670
1744
  /**
1671
- * Tracks custom properties associated with a `FieldNode`.
1745
+ * Tracks custom metadata associated with a `FieldNode`.
1672
1746
  */
1673
- declare class FieldPropertyState {
1747
+ declare class FieldMetadataState {
1674
1748
  private readonly node;
1675
- /** A map of all `Property` and `AggregateProperty` that have been defined for this field. */
1676
- private readonly properties;
1749
+ /** A map of all `MetadataKey` and `AggregateMetadataKey` that have been defined for this field. */
1750
+ private readonly metadata;
1677
1751
  constructor(node: FieldNode);
1678
- /** Gets the value of a `Property` or `AggregateProperty` for the field. */
1679
- get<T>(prop: Property<T> | AggregateProperty<T, unknown>): T | undefined | Signal<T>;
1680
- /**
1681
- * Checks whether the current property state has the given property.
1682
- * @param prop
1683
- * @returns
1684
- */
1685
- has(prop: Property<unknown> | AggregateProperty<unknown, unknown>): boolean;
1752
+ /** Gets the value of a `MetadataKey` or `AggregateMetadataKey` for the field. */
1753
+ get<T>(key: MetadataKey<T> | AggregateMetadataKey<T, unknown>): T | undefined | Signal<T>;
1754
+ /** Checks whether the current metadata state has the given metadata key. */
1755
+ has(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean;
1686
1756
  }
1687
1757
 
1688
1758
  /**
@@ -1793,7 +1863,7 @@ declare class FieldSubmitState {
1793
1863
  */
1794
1864
  readonly selfSubmitting: WritableSignal<boolean>;
1795
1865
  /** Server errors that are associated with this field. */
1796
- readonly serverErrors: WritableSignal<readonly ValidationError[]>;
1866
+ readonly serverErrors: WritableSignal<readonly ValidationErrorWithField[]>;
1797
1867
  constructor(node: FieldNode);
1798
1868
  /**
1799
1869
  * Whether this form is currently in the process of being submitted.
@@ -1807,14 +1877,14 @@ interface ValidationState {
1807
1877
  * The full set of synchronous tree errors visible to this field. This includes ones that are
1808
1878
  * targeted at a descendant field rather than at this field.
1809
1879
  */
1810
- rawSyncTreeErrors: Signal<ValidationError[]>;
1880
+ rawSyncTreeErrors: Signal<ValidationErrorWithField[]>;
1811
1881
  /**
1812
1882
  * The full set of synchronous errors for this field, including synchronous tree errors and server
1813
1883
  * errors. Server errors are considered "synchronous" because they are imperatively added. From
1814
1884
  * the perspective of the field state they are either there or not, they are never in a pending
1815
1885
  * state.
1816
1886
  */
1817
- syncErrors: Signal<ValidationError[]>;
1887
+ syncErrors: Signal<ValidationErrorWithField[]>;
1818
1888
  /**
1819
1889
  * Whether the field is considered valid according solely to its synchronous validators.
1820
1890
  * Errors resulting from a previous submit attempt are also considered for this state.
@@ -1825,21 +1895,21 @@ interface ValidationState {
1825
1895
  * targeted at a descendant field rather than at this field, as well as sentinel 'pending' values
1826
1896
  * indicating that the validator is still running and an error could still occur.
1827
1897
  */
1828
- rawAsyncErrors: Signal<(ValidationError | 'pending')[]>;
1898
+ rawAsyncErrors: Signal<(ValidationErrorWithField | 'pending')[]>;
1829
1899
  /**
1830
1900
  * The asynchronous tree errors visible to this field that are specifically targeted at this field
1831
1901
  * rather than a descendant. This also includes all 'pending' sentinel values, since those could
1832
1902
  * theoretically result in errors for this field.
1833
1903
  */
1834
- asyncErrors: Signal<(ValidationError | 'pending')[]>;
1904
+ asyncErrors: Signal<(ValidationErrorWithField | 'pending')[]>;
1835
1905
  /**
1836
1906
  * The combined set of all errors that currently apply to this field.
1837
1907
  */
1838
- errors: Signal<ValidationError[]>;
1908
+ errors: Signal<ValidationErrorWithField[]>;
1839
1909
  /**
1840
1910
  * The combined set of all errors that currently apply to this field and its descendants.
1841
1911
  */
1842
- errorSummary: Signal<ValidationError[]>;
1912
+ errorSummary: Signal<ValidationErrorWithField[]>;
1843
1913
  /**
1844
1914
  * Whether this field has any asynchronous validators still pending.
1845
1915
  */
@@ -1907,7 +1977,7 @@ interface ValidationState {
1907
1977
  declare class FieldNode implements FieldState<unknown> {
1908
1978
  readonly structure: FieldNodeStructure;
1909
1979
  readonly validationState: ValidationState;
1910
- readonly propertyState: FieldPropertyState;
1980
+ readonly metadataState: FieldMetadataState;
1911
1981
  readonly nodeState: FieldNodeState;
1912
1982
  readonly submitState: FieldSubmitState;
1913
1983
  private _context;
@@ -1921,8 +1991,8 @@ declare class FieldNode implements FieldState<unknown> {
1921
1991
  get logicNode(): LogicNode;
1922
1992
  get value(): WritableSignal<unknown>;
1923
1993
  get keyInParent(): Signal<string | number>;
1924
- get errors(): Signal<ValidationError[]>;
1925
- get errorSummary(): Signal<ValidationError[]>;
1994
+ get errors(): Signal<ValidationErrorWithField[]>;
1995
+ get errorSummary(): Signal<ValidationErrorWithField[]>;
1926
1996
  get pending(): Signal<boolean>;
1927
1997
  get valid(): Signal<boolean>;
1928
1998
  get invalid(): Signal<boolean>;
@@ -1935,15 +2005,16 @@ declare class FieldNode implements FieldState<unknown> {
1935
2005
  get fieldBindings(): Signal<readonly Field<unknown>[]>;
1936
2006
  get submitting(): Signal<boolean>;
1937
2007
  get name(): Signal<string>;
1938
- get max(): Signal<number | undefined>;
1939
- get maxLength(): Signal<number | undefined>;
1940
- get min(): Signal<number | undefined>;
1941
- get minLength(): Signal<number | undefined>;
1942
- get pattern(): Signal<readonly RegExp[]>;
1943
- get required(): Signal<boolean>;
1944
- property<M>(prop: AggregateProperty<M, any>): Signal<M>;
1945
- property<M>(prop: Property<M>): M | undefined;
1946
- hasProperty(prop: Property<unknown> | AggregateProperty<unknown, any>): boolean;
2008
+ private metadataOrUndefined;
2009
+ get max(): Signal<number | undefined> | undefined;
2010
+ get maxLength(): Signal<number | undefined> | undefined;
2011
+ get min(): Signal<number | undefined> | undefined;
2012
+ get minLength(): Signal<number | undefined> | undefined;
2013
+ get pattern(): Signal<readonly RegExp[]> | undefined;
2014
+ get required(): Signal<boolean> | undefined;
2015
+ metadata<M>(key: AggregateMetadataKey<M, any>): Signal<M>;
2016
+ metadata<M>(key: MetadataKey<M>): M | undefined;
2017
+ hasMetadata(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean;
1947
2018
  /**
1948
2019
  * Marks this specific field as touched.
1949
2020
  */
@@ -2485,7 +2556,7 @@ type BaseValidatorConfig<TValue, TPathKind extends PathKind = PathKind.Root> = {
2485
2556
  * Custom validation error(s) to report instead of the default,
2486
2557
  * or a function that receives the `FieldContext` and returns custom validation error(s).
2487
2558
  */
2488
- error?: OneOrMany<WithoutField<ValidationError>> | LogicFn<TValue, OneOrMany<WithoutField<ValidationError>>, TPathKind>;
2559
+ error?: OneOrMany<ValidationError> | LogicFn<TValue, OneOrMany<ValidationError>, TPathKind>;
2489
2560
  message?: never;
2490
2561
  };
2491
2562
 
@@ -2650,5 +2721,5 @@ type IgnoreUnknownProperties<T> = T extends Record<PropertyKey, unknown> ? {
2650
2721
  */
2651
2722
  declare function validateStandardSchema<TSchema, TValue extends IgnoreUnknownProperties<TSchema>>(path: FieldPath<TValue>, schema: StandardSchemaV1<TSchema>): void;
2652
2723
 
2653
- export { AggregateProperty, CustomValidationError, EmailValidationError, FIELD, Field, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MaxLengthValidationError, MaxValidationError, MinLengthValidationError, MinValidationError, NgValidationError, PATTERN, PathKind, PatternValidationError, Property, REQUIRED, RequiredValidationError, StandardSchemaValidationError, aggregateProperty, andProperty, apply, applyEach, applyWhen, applyWhenValue, createProperty, customError, disabled, email, emailError, form, hidden, listProperty, max, maxError, maxLength, maxLengthError, maxProperty, min, minError, minLength, minLengthError, minProperty, orProperty, pattern, patternError, property, readonly, reducedProperty, required, requiredError, schema, standardSchemaError, submit, validate, validateAsync, validateHttp, validateStandardSchema, validateTree };
2654
- export type { AsyncValidationResult, AsyncValidatorOptions, ChildFieldContext, DisabledReason, FieldContext, FieldPath, FieldState, FieldTree, FieldValidationResult, FieldValidator, FormCheckboxControl, FormOptions, FormUiControl, FormValueControl, HttpValidatorOptions, IgnoreUnknownProperties, ItemFieldContext, LogicFn, MapToErrorsFn, MaybeFieldPath, MaybeFieldTree, Mutable, OneOrMany, ReadonlyArrayLike, RemoveStringIndexUnknownKey, RootFieldContext, Schema, SchemaFn, SchemaOrSchemaFn, Subfields, SubmittedStatus, TreeValidationResult, TreeValidator, ValidationError, ValidationResult, ValidationSuccess, Validator, WithField, WithOptionalField, WithoutField };
2724
+ export { AggregateMetadataKey, CustomValidationError, EmailValidationError, FIELD, Field, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MaxLengthValidationError, MaxValidationError, MetadataKey, MinLengthValidationError, MinValidationError, NgValidationError, PATTERN, PathKind, PatternValidationError, REQUIRED, RequiredValidationError, StandardSchemaValidationError, aggregateMetadata, andMetadataKey, apply, applyEach, applyWhen, applyWhenValue, createMetadataKey, customError, disabled, email, emailError, form, hidden, listMetadataKey, max, maxError, maxLength, maxLengthError, maxMetadataKey, metadata, min, minError, minLength, minLengthError, minMetadataKey, orMetadataKey, pattern, patternError, readonly, reducedMetadataKey, required, requiredError, schema, standardSchemaError, submit, validate, validateAsync, validateHttp, validateStandardSchema, validateTree };
2725
+ export type { AsyncValidationResult, AsyncValidatorOptions, ChildFieldContext, DisabledReason, FieldContext, FieldPath, FieldState, FieldTree, FieldValidator, FormCheckboxControl, FormOptions, FormUiControl, FormValueControl, HttpValidatorOptions, IgnoreUnknownProperties, ItemFieldContext, LogicFn, MapToErrorsFn, MaybeFieldPath, MaybeFieldTree, OneOrMany, ReadonlyArrayLike, RemoveStringIndexUnknownKey, RootFieldContext, Schema, SchemaFn, SchemaOrSchemaFn, Subfields, SubmittedStatus, TreeValidationResult, TreeValidator, ValidationError, ValidationErrorWithField, ValidationErrorWithOptionalField, ValidationErrorWithoutField, ValidationResult, ValidationSuccess, Validator, WithField, WithOptionalField, WithoutField };