Getting Started
Build your first type-safe form with antd-typed.
This guide walks through building a form with full type safety and schema validation.
Quick Start
Define a Schema
Create a schema that describes your form structure. This example uses Zod, but any Standard Schema library works.
import { } from "zod";
const = .({
: .().(3, "Username must be at least 3 characters"),
: .().("Invalid email address"),
: ..().(18, "Must be 18 or older"),
});The schema serves as the single source of truth for types and validation.
Create the Form
Use useForm with your schema. It returns typed components that enforce your schema structure.
import { } from "antd-typed";
import { , , } from "antd";
function () {
const { , } = ({
: ,
: () => {
// values is fully typed as { username: string; email: string; age: number }
.();
},
});
return (
< ="vertical">
< ="username" ="Username">
< />
</>
< ="email" ="Email">
< />
</>
< ="age" ="Age">
< ={{ : "100%" }} />
</>
< ="primary" ="submit">
Submit
</>
</>
);
}Type Safety in Action
The FormItem component only accepts field names that exist in your schema. Typos are caught at compile time.
import React from "react";
import { } from "zod";
import { } from "antd-typed";
import { } from "antd";
const = .({
: .(),
: .().(),
});
function () {
const { } = ({ : });
return (
<>
< name="usernam"> < />
</>
</>
);
}What useForm Returns
The hook returns everything you need to build forms:
| Return | Description |
|---|---|
Form | A typed wrapper around Ant Design's Form |
FormItem | Type-safe form field with autocomplete for name |
FormList | Type-safe dynamic field list |
form | The Ant Design form instance for imperative operations |
formProps | Props to spread on a standard <Form> if preferred |
useWatch | Type-safe field value watcher |
Migration from Ant Design
If you have an existing form, migration is straightforward:
// Before
import { Form } from "antd";
function MyForm() {
const [form] = Form.useForm();
return (
<Form form={form} onFinish={(values) => console.log(values)}>
<Form.Item name="email">
<Input />
</Form.Item>
</Form>
);
}
// After
import { useForm } from "antd-typed";
function MyForm() {
const { Form, FormItem } = useForm({
validator: mySchema,
onFinish: (values) => console.log(values),
});
return (
<Form>
<FormItem name="email">
<Input />
</FormItem>
</Form>
);
}The structure stays the same. You gain types and validation by adding a schema.