vee-validate icon indicating copy to clipboard operation
vee-validate copied to clipboard

TypeScript inference issue with Form @submit and zod schema in Vue 3

Open smile-alive opened this issue 6 months ago • 0 comments

What happened?

When using <Form @submit="..." /> with zod schema + TypeScript, the @submit event type does not merge my custom fields correctly with the inferred schema type.

Here is my setup:

<Form
  v-slot="{ meta }"
  :validation-schema="toTypedSchema(schema)"
  :initial-values="{ email: userStore.email }"
  @submit="download({ ...$event, type: 'csv', data: selectedItems })"
>
  <FormField name="email" validate-on-blur />
  <Button type="submit">发送</Button>
</Form>

const schema = z.object({
  email: z.string().trim().email({ message: '邮箱格式错误' }),
});

interface DownloadParams extends z.infer<typeof schema> {
  data: Poi[];
  type: 'csv' | 'vcard';
}

const { mutate: download } = useMutation({
  mutation(values: DownloadParams) {
    return $post('/api/amap/downloads', values);
  },
});

The error I get

Argument of type 
  '{ type: "csv"; data: Poi[]; }'
is not assignable to parameter of type 'DownloadParams'.

Even though I’m spreading $event (the form values) and adding type + data, TypeScript doesn’t infer that $event already satisfies z.infer ({ email: string }).

Expected behavior

The @submit event payload should be strongly typed with the schema and allow extending it with additional fields when passing into other typed functions.

For example, the following should typecheck correctly:

@submit="download({ ...$event, type: 'csv', data: selectedItems })"
"@amap/amap-jsapi-loader": "^1.0.1",
		"@pinia/colada": "^0.17.1",
		"@vee-validate/zod": "^4.15.1",
		"@vueuse/core": "^13.7.0",
		"axios": "^1.11.0",
		"class-variance-authority": "^0.7.1",
		"clsx": "^2.1.1",
		"dayjs": "^1.11.13",
		"es-toolkit": "^1.39.9",
		"lucide-vue-next": "^0.539.0",
		"pinia": "^3.0.3",
		"pinia-plugin-persistedstate": "^4.5.0",
		"reka-ui": "^2.4.1",
		"tailwind-merge": "^3.3.1",
		"vaul-vue": "^0.4.1",
		"vconsole": "^3.15.1",
		"vee-validate": "^4.15.1",
		"vue": "^3.5.18",
		"vue-router": "^4.5.1",
		"vue-sonner": "^2.0.2",
		"zod": "^3.25.76"

Reproduction steps

...

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

  • [ ] Firefox
  • [ ] Chrome
  • [ ] Safari
  • [ ] Microsoft Edge

Relevant log output


Demo link

x

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

smile-alive avatar Aug 22 '25 14:08 smile-alive