@@ -25,35 +25,26 @@ import type {
25
25
import { RuntimeErrorCode } from './errors' ;
26
26
import type { AbstractControl } from './model/abstract_model' ;
27
27
28
- function isEmptyInputValue ( value : any ) : boolean {
29
- /**
30
- * Check if the object is a string or array before evaluating the length attribute.
31
- * Check if the object is a set before evaluating the size attribute.
32
- * This avoids falsely rejecting objects that contain a custom length or size attribute.
33
- * For example, the object {id: 1, length: 0, width: 0} should not be returned as empty.
34
- */
35
- return (
36
- value == null ||
37
- ( ( typeof value === 'string' || Array . isArray ( value ) ) && value . length === 0 ) ||
38
- ( value instanceof Set && value . size === 0 )
39
- ) ;
28
+ function isEmptyInputValue ( value : unknown ) : boolean {
29
+ return value == null || lengthOrSize ( value ) === 0 ;
40
30
}
41
31
42
32
/**
43
- * Extract the length property in case it's an array.
33
+ * Extract the length property in case it's an array or a string .
44
34
* Extract the size property in case it's a set.
45
35
* Return null else.
46
36
* @param value Either an array, set or undefined.
47
37
*/
48
- function lengthOrSize ( value : any ) : number | null {
38
+ function lengthOrSize ( value : unknown ) : number | null {
49
39
// non-strict comparison is intentional, to check for both `null` and `undefined` values
50
40
if ( value == null ) {
51
41
return null ;
52
- } else if ( typeof value . length === 'number ' ) {
42
+ } else if ( Array . isArray ( value ) || typeof value === 'string ' ) {
53
43
return value . length ;
54
- } else if ( typeof value . size === 'number' ) {
44
+ } else if ( value instanceof Set ) {
55
45
return value . size ;
56
46
}
47
+
57
48
return null ;
58
49
}
59
50
@@ -474,7 +465,7 @@ export class Validators {
474
465
*/
475
466
export function minValidator ( min : number ) : ValidatorFn {
476
467
return ( control : AbstractControl ) : ValidationErrors | null => {
477
- if ( isEmptyInputValue ( control . value ) || isEmptyInputValue ( min ) ) {
468
+ if ( control . value == null || min == null ) {
478
469
return null ; // don't validate empty values to allow optional controls
479
470
}
480
471
const value = parseFloat ( control . value ) ;
@@ -490,7 +481,7 @@ export function minValidator(min: number): ValidatorFn {
490
481
*/
491
482
export function maxValidator ( max : number ) : ValidatorFn {
492
483
return ( control : AbstractControl ) : ValidationErrors | null => {
493
- if ( isEmptyInputValue ( control . value ) || isEmptyInputValue ( max ) ) {
484
+ if ( control . value == null || max == null ) {
494
485
return null ; // don't validate empty values to allow optional controls
495
486
}
496
487
const value = parseFloat ( control . value ) ;
@@ -531,11 +522,14 @@ export function emailValidator(control: AbstractControl): ValidationErrors | nul
531
522
/**
532
523
* Validator that requires the number of items in the control's value to be greater than or equal
533
524
* to the provided minimum length. See `Validators.minLength` for additional information.
525
+ *
526
+ * The minLengthValidator respects every length property in an object, regardless of whether it's an array.
527
+ * For example, the object {id: 1, length: 0, width: 0} should be validated.
534
528
*/
535
529
export function minLengthValidator ( minLength : number ) : ValidatorFn {
536
530
return ( control : AbstractControl ) : ValidationErrors | null => {
537
- const length = lengthOrSize ( control . value ) ;
538
- if ( isEmptyInputValue ( control . value ) || ! length ) {
531
+ const length = control . value ?. length ?? lengthOrSize ( control . value ) ;
532
+ if ( length === null || length === 0 ) {
539
533
// don't validate empty values to allow optional controls
540
534
// don't validate values without `length` or `size` property
541
535
return null ;
@@ -550,10 +544,13 @@ export function minLengthValidator(minLength: number): ValidatorFn {
550
544
/**
551
545
* Validator that requires the number of items in the control's value to be less than or equal
552
546
* to the provided maximum length. See `Validators.maxLength` for additional information.
547
+ *
548
+ * The maxLengthValidator respects every length property in an object, regardless of whether it's an array.
549
+ * For example, the object {id: 1, length: 0, width: 0} should be validated.
553
550
*/
554
551
export function maxLengthValidator ( maxLength : number ) : ValidatorFn {
555
552
return ( control : AbstractControl ) : ValidationErrors | null => {
556
- const length = lengthOrSize ( control . value ) ;
553
+ const length = control . value ?. length ?? lengthOrSize ( control . value ) ;
557
554
if ( length !== null && length > maxLength ) {
558
555
return { 'maxlength' : { 'requiredLength' : maxLength , 'actualLength' : length } } ;
559
556
}
0 commit comments