Draco
Draco2mo ago

Validator confusion

Why is my intellisense showing me a different type, but then my function actually getting a different one?
No description
5 Replies
Draco
DracoOP2mo ago
Also The ai on the website does telll me to add these other optional fields to the validator But is there a helper for this perchance that idk about? Something like the WithoutSystemFields<> thing? But for having the system fields? Or a way to strip the system fields in the query?
djbalin
djbalin2mo ago
You can read a bit about the return value behavior here: https://docs.convex.dev/functions/validation#adding-validators intellisense is probably inferring what your actual handler code is doing. You are calling collect() which returns documents - these have _id and _creationTime. You specifically dont want to return _id and _creationTime to the client? you would just have to map the results: Something along these lines:
const docsWithoutSystemFields = (await ctx.db.query("page").collect()).map(doc => {
const {_id, _creationTime, ...rest} = doc
return doc
})

return docsWithoutSystemFields
const docsWithoutSystemFields = (await ctx.db.query("page").collect()).map(doc => {
const {_id, _creationTime, ...rest} = doc
return doc
})

return docsWithoutSystemFields
you could easily extract this logic into your own helper to strip system fields from a document.
Argument and Return Value Validation | Convex Developer Hub
Validate function arguments and return values for security
Draco
DracoOP2mo ago
Ahh thanks alot, makes sense Just to be clear, is it usually reccomended to have the "returns" value anyways? Even if it's being inferred?
djbalin
djbalin2mo ago
Nah I wouldn't use return validators unless you have some very specific reason to do it. They can be a bit difficult to work with imo and I haven't needed the functionality they provide. Your original question is a great example of the benefit they provide, however: runtime validation. Typescript has some strange quirks sometimes, especially what you experienced: TS doesnt complain if an object contains more fields than its type specifies. Your return validator on the function then actually catches that. But thats typically not really that useful. What I personally like to do, however, is specify return type on the handler function:
export const getSubmissionsEnrichedPaginated = authQuery({
args: { profileId: v.id("profile"), paginationOpts: paginationOptsValidator },
handler: async (
ctx,
{ profileId, paginationOpts },
): Promise<PaginationResult<ProfileSubmissionEnriched>>
export const getSubmissionsEnrichedPaginated = authQuery({
args: { profileId: v.id("profile"), paginationOpts: paginationOptsValidator },
handler: async (
ctx,
{ profileId, paginationOpts },
): Promise<PaginationResult<ProfileSubmissionEnriched>>
but this is also not necessary (and some philosophies prefer specifically to not do it). i like it for readability, developer intentionality, and not least because it localizes return type mismatches a bit more
Draco
DracoOP2mo ago
Right, thanks again, man !

Did you find this page helpful?