using compose with isArrayOf throws error
alveshelio opened this issue · comments
Hi,
I have this validation
import { create, enforce, test } from 'vest'
import compose from 'vest/enforce/compose'
import { partial } from 'vest/enforce/schema'
import { useFormValidationMessages } from '@messages'
import { SelectedTechnology } from '@models'
export function useTechnologiesFormValidation() {
const formValidationMessages = useFormValidationMessages()
const Technology = compose(
enforce.shape(
partial({
id: enforce.isString(),
value: enforce.isString(),
label: enforce.isString(),
releaseYear: enforce.isString(),
yearsOfExperience: enforce.isString(),
warningInput: enforce.isBoolean(),
})
)
)
return create('TechnologiesForm', (data: TechnologiesFormData) => {
test('yearsOfExperience', formValidationMessages.format('fieldRequired'), () => {
enforce(data.yearsOfExperience).isNotBlank()
})
test('programmingLanguages', formValidationMessages.format('fieldRequired'), () => {
enforce(data.programmingLanguages)
.isArrayOf(Technology)
.longerThanOrEquals(1)
.shorterThanOrEquals(3)
})
test('frameworks', formValidationMessages.format('fieldRequired'), () => {
enforce(data.frameworks).isArrayOf(Technology).longerThanOrEquals(1).shorterThanOrEquals(10)
})
})
}
But this is throwing a TypeScript error
TS2345: Argument of type 'TComposeResult' is not assignable to parameter of type 'TLazy'.
Type 'TComposeResult' is missing the following properties from type 'IRules': isArrayOf, loose, shape, optional, and 57 more.
If I define Technology
like so
const Technology = compose(
enforce.shape({
id: enforce.optional(enforce.isString()),
value: enforce.isString(),
label: enforce.isString(),
releaseYear: enforce.isString(),
yearsOfExperience: enforce.isString(),
warningInput: enforce.optional(enforce.isBoolean()),
})
)
Then I get this error
and I still have the TypeScript error in Technology.
I'm not sure if this is the best approach to validate an array of objects.
Also, how can I define a message for longerThanOrEquals
or shorterThanOrEquals
?
The validation needs to check if the object in the array has the proper shape but it also needs to validate that the number of objects must be at least 1 and no more than 3 and I'd like to have a message for these two cases too.
Hey @alveshelio, thanks for the detailed report, it really helped me debug the issue. I just tested and I can confirm this issue reproduces on my end as well. I think I found its cause, it looks like the type definition for isArrayOf was too broad and it couldn't make sense of the compose return type which was not as broad. I changed it to use the bare minimum required for a validation, and it seems to fix it on my end.
I am releasing a testing version for you to try, can you please report back if it works fine on your end as well? If it does, I will tomorrow ship it as vest@4.0.3. Here is the change to the code: https://github.com/ealush/vest/pull/774/files
Until then, here's the testing version, I hope it fixes the issue on your end as well.
npm i vest@4.0.3-dev-0bdac6
@alveshelio after some more testing, I released 4.0.3. Please let me know if that solves it for you.