diff --git a/.changeset/quiet-lamps-warn.md b/.changeset/quiet-lamps-warn.md new file mode 100644 index 0000000000..9cd41c0f91 --- /dev/null +++ b/.changeset/quiet-lamps-warn.md @@ -0,0 +1,6 @@ +--- +'@tanstack/react-form-nextjs': patch +'@tanstack/react-form-remix': patch +--- + +Fix `createServerValidate` return types to reflect decoded `FormData` values instead of inferred form values. diff --git a/packages/react-form-nextjs/src/createServerValidate.ts b/packages/react-form-nextjs/src/createServerValidate.ts index b936f1e8e6..1c1a5631d0 100644 --- a/packages/react-form-nextjs/src/createServerValidate.ts +++ b/packages/react-form-nextjs/src/createServerValidate.ts @@ -99,12 +99,11 @@ export const createServerValidate = }) } - const values = (info - ? decode(formData, info) - : decode(formData)) as never as TFormData + const values = info ? decode(formData, info) : decode(formData) + const validationValues = values as never as TFormData const onServerError = (await runValidator({ - value: values, + value: validationValues, validationSource: 'form', })) as UnwrapFormAsyncValidateOrFn | undefined @@ -120,7 +119,7 @@ export const createServerValidate = errorMap: { onServer: onServerError, }, - values, + values: validationValues, errors: onServerErrorVal ? [onServerErrorVal] : [], } diff --git a/packages/react-form-nextjs/tests/createServerValidate.test-d.ts b/packages/react-form-nextjs/tests/createServerValidate.test-d.ts new file mode 100644 index 0000000000..14ff7fd857 --- /dev/null +++ b/packages/react-form-nextjs/tests/createServerValidate.test-d.ts @@ -0,0 +1,19 @@ +import { expectTypeOf, it } from 'vitest' +import { createServerValidate, formOptions } from '../src' + +it('types serverValidate return values as decoded form data', () => { + const serverValidate = createServerValidate({ + ...formOptions({ + defaultValues: { + firstName: '', + age: 0, + }, + }), + onServerValidate: async () => undefined, + }) + + type ServerValidateResult = Awaited> + + expectTypeOf().toEqualTypeOf>() + expectTypeOf().toEqualTypeOf() +}) diff --git a/packages/react-form-remix/src/createServerValidate.ts b/packages/react-form-remix/src/createServerValidate.ts index b936f1e8e6..1c1a5631d0 100644 --- a/packages/react-form-remix/src/createServerValidate.ts +++ b/packages/react-form-remix/src/createServerValidate.ts @@ -99,12 +99,11 @@ export const createServerValidate = }) } - const values = (info - ? decode(formData, info) - : decode(formData)) as never as TFormData + const values = info ? decode(formData, info) : decode(formData) + const validationValues = values as never as TFormData const onServerError = (await runValidator({ - value: values, + value: validationValues, validationSource: 'form', })) as UnwrapFormAsyncValidateOrFn | undefined @@ -120,7 +119,7 @@ export const createServerValidate = errorMap: { onServer: onServerError, }, - values, + values: validationValues, errors: onServerErrorVal ? [onServerErrorVal] : [], } diff --git a/packages/react-form-remix/tests/createServerValidate.test-d.ts b/packages/react-form-remix/tests/createServerValidate.test-d.ts new file mode 100644 index 0000000000..14ff7fd857 --- /dev/null +++ b/packages/react-form-remix/tests/createServerValidate.test-d.ts @@ -0,0 +1,19 @@ +import { expectTypeOf, it } from 'vitest' +import { createServerValidate, formOptions } from '../src' + +it('types serverValidate return values as decoded form data', () => { + const serverValidate = createServerValidate({ + ...formOptions({ + defaultValues: { + firstName: '', + age: 0, + }, + }), + onServerValidate: async () => undefined, + }) + + type ServerValidateResult = Awaited> + + expectTypeOf().toEqualTypeOf>() + expectTypeOf().toEqualTypeOf() +})