diff --git a/src/__snapshots__/zod.test.ts.snap b/src/__snapshots__/zod.test.ts.snap index ce8958fb..203de925 100644 --- a/src/__snapshots__/zod.test.ts.snap +++ b/src/__snapshots__/zod.test.ts.snap @@ -133,6 +133,23 @@ Object { "invalid_type": "Expected number, received string", }, }, + "likedUsers": Object { + "0": Object { + "id": Object { + "message": "Expected number, received string", + "type": "invalid_type", + "types": Object { + "invalid_type": "Expected number, received string", + }, + }, + }, + "message": "Invalid input", + "type": "invalid_union", + "types": Object { + "invalid_type": "Expected undefined, received array", + "invalid_union": "Invalid input", + }, + }, "password": Object { "message": "Should be at least 8 characters", "type": "too_small", diff --git a/src/zod.test.ts b/src/zod.test.ts index eb88ea2c..2b4eb198 100644 --- a/src/zod.test.ts +++ b/src/zod.test.ts @@ -10,6 +10,13 @@ const schema = z author: z.object({ id: z.number(), }), + likedUsers: z + .array( + z.object({ + id: z.number(), + }), + ) + .optional(), count: z.number().positive().int(), date: z.date(), url: z.string().url(), @@ -36,6 +43,7 @@ describe('zodResolver', () => { author: { id: 1, }, + likedUsers: [{ id: 1 }], count: 4, date: new Date(), url: 'https://github.com/react-hook-form/resolvers', @@ -73,6 +81,7 @@ describe('zodResolver', () => { author: { id: '1', }, + likedUsers: [{ id: '1' }], count: -5, date: 'date', password: 'R', diff --git a/src/zod.ts b/src/zod.ts index 0c0da313..c628d457 100644 --- a/src/zod.ts +++ b/src/zod.ts @@ -17,39 +17,48 @@ const parseErrorSchema = ( return {}; } - return zodError.errors.reduce>( - (previous, { path, message, code: type }) => { - const currentPath = convertArrayToPathName(path); + const errors = [...zodError.errors]; + let previous: Record = {}; - return { - ...previous, - ...(path - ? previous[currentPath] && validateAllFieldCriteria - ? { - [currentPath]: appendErrors( - currentPath, - validateAllFieldCriteria, - previous, - type, - message, - ), - } - : { - [currentPath]: previous[currentPath] || { - message, - type, - ...(validateAllFieldCriteria - ? { - types: { [type]: message || true }, - } - : {}), - }, - } - : {}), - }; - }, - {}, - ); + for (const error of errors) { + const { path, message, code: type } = error; + const currentPath = convertArrayToPathName(path); + + if ('unionErrors' in error) { + for (const subErrors of error.unionErrors.map((e) => e.errors)) { + errors.push(...subErrors); + } + } + + previous = { + ...previous, + ...(path + ? previous[currentPath] && validateAllFieldCriteria + ? { + [currentPath]: appendErrors( + currentPath, + validateAllFieldCriteria, + previous, + type, + message, + ), + } + : { + [currentPath]: previous[currentPath] || { + message, + type, + ...(validateAllFieldCriteria + ? { + types: { [type]: message || true }, + } + : {}), + }, + } + : {}), + }; + } + + return previous; }; export const zodResolver = >(