diff --git a/packages/conform-zod/coercion.ts b/packages/conform-zod/coercion.ts index a6a8cd63..cb4c85fe 100644 --- a/packages/conform-zod/coercion.ts +++ b/packages/conform-zod/coercion.ts @@ -118,9 +118,15 @@ export function enableTypeCoercion( } else if (def.typeName === 'ZodNumber') { schema = any() .transform((value) => - coerceString(value, (text) => - text.trim() === '' ? Number.NaN : Number(text), - ), + coerceString(value, (text) => { + const number = Number(text); + + if (isNaN(number)) { + return text; + } + + return number; + }), ) .pipe(type); } else if (def.typeName === 'ZodBoolean') { @@ -132,14 +138,14 @@ export function enableTypeCoercion( } else if (def.typeName === 'ZodDate') { schema = any() .transform((value) => - coerceString(value, (timestamp) => { - const date = new Date(timestamp); + coerceString(value, (text) => { + const date = new Date(text); // z.date() does not expose a quick way to set invalid_date error // This gets around it by returning the original string if it's invalid // See https://github.com/colinhacks/zod/issues/1526 if (isNaN(date.getTime())) { - return timestamp; + return text; } return date; @@ -148,7 +154,15 @@ export function enableTypeCoercion( .pipe(type); } else if (def.typeName === 'ZodBigInt') { schema = any() - .transform((value) => coerceString(value, BigInt)) + .transform((value) => + coerceString(value, (text) => { + try { + return BigInt(text); + } catch { + return text; + } + }), + ) .pipe(type); } else if (def.typeName === 'ZodArray') { schema = any() diff --git a/tests/conform-zod.spec.ts b/tests/conform-zod.spec.ts index d642f1dc..a7797e82 100644 --- a/tests/conform-zod.spec.ts +++ b/tests/conform-zod.spec.ts @@ -400,7 +400,7 @@ describe('conform-zod', () => { ).toEqual({ status: 'error', payload: { test: ' ' }, - error: { test: ['invalid'] }, + error: { test: ['min'] }, reply: expect.any(Function), }); });