@@ -25,35 +25,26 @@ import type {
2525import { RuntimeErrorCode } from './errors' ;
2626import type { AbstractControl } from './model/abstract_model' ;
2727
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 ;
4030}
4131
4232/**
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 .
4434 * Extract the size property in case it's a set.
4535 * Return null else.
4636 * @param value Either an array, set or undefined.
4737 */
48- function lengthOrSize ( value : any ) : number | null {
38+ function lengthOrSize ( value : unknown ) : number | null {
4939 // non-strict comparison is intentional, to check for both `null` and `undefined` values
5040 if ( value == null ) {
5141 return null ;
52- } else if ( typeof value . length === 'number ' ) {
42+ } else if ( Array . isArray ( value ) || typeof value === 'string ' ) {
5343 return value . length ;
54- } else if ( typeof value . size === 'number' ) {
44+ } else if ( value instanceof Set ) {
5545 return value . size ;
5646 }
47+
5748 return null ;
5849}
5950
@@ -474,7 +465,7 @@ export class Validators {
474465 */
475466export function minValidator ( min : number ) : ValidatorFn {
476467 return ( control : AbstractControl ) : ValidationErrors | null => {
477- if ( isEmptyInputValue ( control . value ) || isEmptyInputValue ( min ) ) {
468+ if ( control . value == null || min == null ) {
478469 return null ; // don't validate empty values to allow optional controls
479470 }
480471 const value = parseFloat ( control . value ) ;
@@ -490,7 +481,7 @@ export function minValidator(min: number): ValidatorFn {
490481 */
491482export function maxValidator ( max : number ) : ValidatorFn {
492483 return ( control : AbstractControl ) : ValidationErrors | null => {
493- if ( isEmptyInputValue ( control . value ) || isEmptyInputValue ( max ) ) {
484+ if ( control . value == null || max == null ) {
494485 return null ; // don't validate empty values to allow optional controls
495486 }
496487 const value = parseFloat ( control . value ) ;
@@ -531,11 +522,14 @@ export function emailValidator(control: AbstractControl): ValidationErrors | nul
531522/**
532523 * Validator that requires the number of items in the control's value to be greater than or equal
533524 * 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.
534528 */
535529export function minLengthValidator ( minLength : number ) : ValidatorFn {
536530 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 ) {
539533 // don't validate empty values to allow optional controls
540534 // don't validate values without `length` or `size` property
541535 return null ;
@@ -550,10 +544,13 @@ export function minLengthValidator(minLength: number): ValidatorFn {
550544/**
551545 * Validator that requires the number of items in the control's value to be less than or equal
552546 * 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.
553550 */
554551export function maxLengthValidator ( maxLength : number ) : ValidatorFn {
555552 return ( control : AbstractControl ) : ValidationErrors | null => {
556- const length = lengthOrSize ( control . value ) ;
553+ const length = control . value ?. length ?? lengthOrSize ( control . value ) ;
557554 if ( length !== null && length > maxLength ) {
558555 return { 'maxlength' : { 'requiredLength' : maxLength , 'actualLength' : length } } ;
559556 }
0 commit comments