diff --git a/src/validators/ArrayValidator.ts b/src/validators/ArrayValidator.ts index b2845a43..4582c462 100644 --- a/src/validators/ArrayValidator.ts +++ b/src/validators/ArrayValidator.ts @@ -16,74 +16,74 @@ import { ValidationError } from '../lib/errors/ValidationError'; import { Result } from '../lib/Result'; import { BaseValidator } from './imports'; -export class ArrayValidator extends BaseValidator { - private readonly validator: BaseValidator; +export class ArrayValidator extends BaseValidator { + private readonly validator: BaseValidator; - public constructor(validator: BaseValidator, constraints: readonly IConstraint[] = []) { + public constructor(validator: BaseValidator, constraints: readonly IConstraint[] = []) { super(constraints); this.validator = validator; } - public lengthLessThan(length: N): BaseValidator]>>> { - return this.addConstraint(arrayLengthLessThan(length) as IConstraint) as any; + public lengthLessThan(length: N): ArrayValidator]>>> { + return this.addConstraint(arrayLengthLessThan(length) as IConstraint) as any; } - public lengthLessThanOrEqual(length: N): BaseValidator]>> { - return this.addConstraint(arrayLengthLessThanOrEqual(length)) as any; + public lengthLessThanOrEqual(length: N): ArrayValidator]>> { + return this.addConstraint(arrayLengthLessThanOrEqual(length) as IConstraint) as any; } - public lengthGreaterThan(length: N): BaseValidator<[...Tuple, T, ...T[]]> { - return this.addConstraint(arrayLengthGreaterThan(length)) as any; + public lengthGreaterThan(length: N): ArrayValidator<[...Tuple, I, ...T]> { + return this.addConstraint(arrayLengthGreaterThan(length) as IConstraint) as any; } - public lengthGreaterThanOrEqual(length: N): BaseValidator<[...Tuple, ...T[]]> { - return this.addConstraint(arrayLengthGreaterThanOrEqual(length)) as any; + public lengthGreaterThanOrEqual(length: N): ArrayValidator<[...Tuple, ...T]> { + return this.addConstraint(arrayLengthGreaterThanOrEqual(length) as IConstraint) as any; } - public lengthEqual(length: N): BaseValidator<[...Tuple]> { - return this.addConstraint(arrayLengthEqual(length)) as any; + public lengthEqual(length: N): ArrayValidator<[...Tuple]> { + return this.addConstraint(arrayLengthEqual(length) as IConstraint) as any; } - public lengthNotEqual(length: number): BaseValidator<[...T[]]> { - return this.addConstraint(arrayLengthNotEqual(length)) as any; + public lengthNotEqual(length: number): ArrayValidator<[...T]> { + return this.addConstraint(arrayLengthNotEqual(length) as IConstraint) as any; } public lengthRange( start: S, endBefore: E - ): BaseValidator]>>, ExpandSmallerTuples]>>>> { - return this.addConstraint(arrayLengthRange(start, endBefore)) as any; + ): ArrayValidator]>>, ExpandSmallerTuples]>>>> { + return this.addConstraint(arrayLengthRange(start, endBefore) as IConstraint) as any; } public lengthRangeInclusive( startAt: S, endAt: E - ): BaseValidator]>, ExpandSmallerTuples]>>>> { - return this.addConstraint(arrayLengthRangeInclusive(startAt, endAt)) as any; + ): ArrayValidator]>, ExpandSmallerTuples]>>>> { + return this.addConstraint(arrayLengthRangeInclusive(startAt, endAt) as IConstraint) as any; } public lengthRangeExclusive( startAfter: S, endBefore: E - ): BaseValidator]>>, ExpandSmallerTuples<[...Tuple]>>> { - return this.addConstraint(arrayLengthRangeExclusive(startAfter, endBefore)) as any; + ): ArrayValidator]>>, ExpandSmallerTuples<[...Tuple]>>> { + return this.addConstraint(arrayLengthRangeExclusive(startAfter, endBefore) as IConstraint) as any; } protected override clone(): this { return Reflect.construct(this.constructor, [this.validator, this.constraints]); } - protected handle(values: unknown): Result { + protected handle(values: unknown): Result { if (!Array.isArray(values)) { return Result.err(new ValidationError('s.array(T)', 'Expected an array', values)); } if (!this.shouldRunConstraints) { - return Result.ok(values); + return Result.ok(values as T); } const errors: [number, BaseError][] = []; - const transformed: T[] = []; + const transformed: T = [] as unknown as T; for (let i = 0; i < values.length; i++) { const result = this.validator.run(values[i]); diff --git a/src/validators/BaseValidator.ts b/src/validators/BaseValidator.ts index c9987ccc..10eadc74 100644 --- a/src/validators/BaseValidator.ts +++ b/src/validators/BaseValidator.ts @@ -29,8 +29,8 @@ export abstract class BaseValidator { return new UnionValidator([new NullishValidator(), this.clone()]); } - public get array(): ArrayValidator { - return new ArrayValidator(this.clone()); + public get array(): ArrayValidator { + return new ArrayValidator(this.clone()); } public get set(): SetValidator { diff --git a/tests/validators/array.test.ts b/tests/validators/array.test.ts index bbcec527..860ec6d8 100644 --- a/tests/validators/array.test.ts +++ b/tests/validators/array.test.ts @@ -175,6 +175,21 @@ describe('ArrayValidator', () => { ); }); }); + + describe('chainedLengthCheck', () => { + const lengthRangePredicate = s.string.array.lengthGreaterThan(0).lengthLessThan(2); + + test.each([[['foo']]])('GIVEN %j THEN returns given value', (value) => { + expect(lengthRangePredicate.parse(value)).toEqual(value); + }); + + test.each([[['hewwo', 'there']]])('GIVEN %j THEN throws ConstraintError', (value) => { + expectError( + () => lengthRangePredicate.parse(value), + new ExpectedConstraintError('s.array(T).lengthLessThan', 'Invalid Array length', value, 'expected.length < 2') + ); + }); + }); }); test('GIVEN clone THEN returns similar instance', () => {