У меня есть форма в svelte, использую shadcn-svelte и zod.
Соответствующие фрагменты кода:
// schema.ts
const formSchema = z.object({
/* ... */
maxParticipants: z.number()
});
<!-- form.svelte -->
<Form.Field {form} name = "maxParticipants">
<Form.Control let:attrs>
<Form.Label>Max participants</Form.Label>
<Input {...attrs} type = "number" bind:value = {$formData.maxParticipants} />
</Form.Control>
<Form.FieldErrors />
</Form.Field>
Поскольку входные данные представляют собой строки, даже если для входных данных установлено значение type = "number"
, это строка, а это означает, что когда я пытаюсь отправить, я получаю ошибку под входными данными (в FieldErrors
, из проверки zod): «Ожидаемое число получено нить".
Я не мог найти способ сделать это, поэтому все, что у меня сейчас есть, это просто установить входные данные на type = "text"
и .string()
в схеме zod, а затем в действиях, где я обрабатываю отправку формы, привести его к числу , но это было бы очень не оптимально.
Для элементов input
type = "number"
Svelte преобразует значение в число при привязке, но type
должно быть статически известно, что, вероятно, не является причиной для этого компонента (поскольку здесь передается тип).
Вы можете создать более конкретный NumberInput
, который статически устанавливает тип внутри, тогда привязка значения будет давать number
или null
(если пусто).
Альтернативно, не используйте привязку и используйте событие для получения значения.
Что-то вроде:
<Input
value = {$formData.maxParticipants?.toString() ?? ''}
on:change = {e => $formData.maxParticipants = parseInt(e.target.value)} />
(Это сделано только для иллюстрации подхода и не обрабатывает все должным образом, например, в случаях с пустым пространством или только с пробелами.)
Вам просто нужно извлечь код функции в <script>
и использовать утверждения типа. В Svelte 5 это также будет возможно в шаблоне.
Спасибо! но - Когда я использую TypeScript,
e.target
не имеет свойстваvalue
. Обычно это делается в HTMLInputElement, но вы не можете использовать эти элементы в стройной разметке (as
,: number
и т. д.). Это означает, что второй подход не сработает. Не могли бы вы предоставить общий фрагмент первого подхода?