@zod-utils/react-hook-form 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,34 +1,79 @@
1
1
  # @zod-utils/react-hook-form
2
2
 
3
-
4
3
  [![npm version](https://img.shields.io/npm/v/@zod-utils/react-hook-form.svg)](https://www.npmjs.com/package/@zod-utils/react-hook-form)
5
4
  [![npm downloads](https://img.shields.io/npm/dm/@zod-utils/react-hook-form.svg)](https://www.npmjs.com/package/@zod-utils/react-hook-form)
5
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@zod-utils/react-hook-form)](https://bundlephobia.com/package/@zod-utils/react-hook-form)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
8
8
  [![CI](https://github.com/thu-san/zod-utils/workflows/CI/badge.svg)](https://github.com/thu-san/zod-utils/actions)
9
+ [![codecov](https://codecov.io/gh/thu-san/zod-utils/branch/main/graph/badge.svg?flag=react-hook-form)](https://codecov.io/gh/thu-san/zod-utils)
10
+
9
11
  React Hook Form integration and utilities for Zod schemas.
10
12
 
13
+ ## 💡 Why Use This?
14
+
15
+ **The whole point:** Automatically transforms your Zod schema types so form inputs accept `undefined` (and `null` for objects only) during editing, while the validated output remains exactly as your Zod schema defines.
16
+
17
+ No more type wrestling with React Hook Form - just pass your schema and it works.
18
+
19
+ ```typescript
20
+ import { useZodForm } from "@zod-utils/react-hook-form";
21
+ import { z } from "zod";
22
+
23
+ // Your schema with primitives, arrays, and objects - NOT optional
24
+ const schema = z.object({
25
+ username: z.string().min(3),
26
+ age: z.number().min(18),
27
+ tags: z.array(z.string()),
28
+ profile: z.object({ bio: z.string() }),
29
+ });
30
+
31
+ const form = useZodForm({ schema });
32
+
33
+ // ✅ Works! Primitives and arrays accept undefined during editing
34
+ form.setValue("username", undefined);
35
+ form.setValue("age", undefined);
36
+ form.setValue("tags", undefined);
37
+
38
+ // ✅ Works! Objects accept both null and undefined
39
+ form.setValue("profile", null);
40
+ form.setValue("profile", undefined);
41
+
42
+ // ✅ Validated output type is exactly z.infer<typeof schema>
43
+ const onSubmit = form.handleSubmit((data) => {
44
+ // Type: { username: string; age: number; tags: string[]; profile: { bio: string } }
45
+ // NOT { username: string | null | undefined; ... }
46
+ console.log(data.username); // Type: string
47
+ console.log(data.age); // Type: number
48
+ console.log(data.tags); // Type: string[]
49
+ console.log(data.profile); // Type: { bio: string }
50
+ });
51
+ ```
52
+
11
53
  ## Installation
12
54
 
13
55
  ```bash
14
56
  npm install @zod-utils/react-hook-form zod react react-hook-form @hookform/resolvers
15
57
  ```
16
58
 
59
+ ## Related Packages
60
+
61
+ - **[@zod-utils/core](https://www.npmjs.com/package/@zod-utils/core)** - Pure TypeScript utilities for Zod schema manipulation (no React dependencies). All utilities are re-exported from this package for convenience.
62
+
17
63
  ## Features
18
64
 
19
- - 🎣 **useZodForm** - Type-safe React Hook Form integration
20
- - 🌐 **Custom error messages** - Japanese error resolver (customizable)
65
+ - 🎣 **useZodForm** - Automatic type transformation for form inputs (nullable/undefined) while preserving Zod schema validation
21
66
  - 📦 **All core utilities** - Re-exports everything from `@zod-utils/core`
22
67
  - ⚛️ **React-optimized** - Built specifically for React applications
23
68
 
24
69
  ## Quick Start
25
70
 
26
71
  ```typescript
27
- import { useZodForm, getSchemaDefaults } from '@zod-utils/react-hook-form';
28
- import { z } from 'zod';
72
+ import { useZodForm, getSchemaDefaults } from "@zod-utils/react-hook-form";
73
+ import { z } from "zod";
29
74
 
30
75
  const schema = z.object({
31
- name: z.string().default('John Doe'),
76
+ name: z.string().default("John Doe"),
32
77
  email: z.string().email(),
33
78
  age: z.number().min(18),
34
79
  });
@@ -45,9 +90,9 @@ function MyForm() {
45
90
 
46
91
  return (
47
92
  <form onSubmit={onSubmit}>
48
- <input {...form.register('name')} />
49
- <input {...form.register('email')} type="email" />
50
- <input {...form.register('age')} type="number" />
93
+ <input {...form.register("name")} />
94
+ <input {...form.register("email")} type="email" />
95
+ <input {...form.register("age")} type="number" />
51
96
  <button type="submit">Submit</button>
52
97
  </form>
53
98
  );
@@ -61,8 +106,8 @@ function MyForm() {
61
106
  Type-safe wrapper around React Hook Form's `useForm` with automatic Zod schema integration.
62
107
 
63
108
  ```typescript
64
- import { useZodForm } from '@zod-utils/react-hook-form';
65
- import { z } from 'zod';
109
+ import { useZodForm } from "@zod-utils/react-hook-form";
110
+ import { z } from "zod";
66
111
 
67
112
  const schema = z.object({
68
113
  username: z.string().min(3),
@@ -70,124 +115,164 @@ const schema = z.object({
70
115
  });
71
116
 
72
117
  const form = useZodForm({
73
- schema, // Zod schema (required)
74
- defaultValues: { /* ... */ }, // Optional default values
75
- zodResolverOptions: { /* ... */ }, // Optional zodResolver options
118
+ schema, // Zod schema (required)
119
+ defaultValues: {
120
+ /* ... */
121
+ }, // Optional default values
122
+ zodResolverOptions: {
123
+ /* ... */
124
+ }, // Optional zodResolver options
76
125
  // ... all other useForm options
77
126
  });
78
127
  ```
79
128
 
80
- **Automatically sets up:**
81
- - Zod schema validation via `zodResolver`
82
- - Proper TypeScript typing
83
- - Form state management
129
+ **What it does:**
84
130
 
85
- ---
131
+ - **Input transformation** (by default):
132
+ - **Primitive fields** (string, number, boolean) accept `undefined` only
133
+ - **Array fields** accept `undefined` only
134
+ - **Object fields** accept both `null` and `undefined`
135
+ - You can override this by specifying a custom input type (see examples below)
136
+ - **Output validation**: Validated data matches your Zod schema exactly
137
+ - **Type inference**: No manual type annotations needed - everything is inferred from the schema
138
+ - **Zod integration**: Automatically sets up `zodResolver` for validation
86
139
 
87
- ### `customErrorResolver(config)`
140
+ #### Custom Input Types
88
141
 
89
- Custom error message resolver with Japanese translations. Easily customizable for other languages.
142
+ You can override the default input type transformation if needed:
90
143
 
91
144
  ```typescript
92
- import { customErrorResolver, FieldNamespaceMapping } from '@zod-utils/react-hook-form';
93
- import { z } from 'zod';
94
-
95
- // Extend the field namespace mapping
96
- const MyFieldNamespaceMapping = {
97
- ...FieldNamespaceMapping,
98
- myForm: {
99
- username: 'ユーザー名',
100
- email: 'メールアドレス',
101
- },
102
- };
103
-
104
- const errorMap = customErrorResolver({
105
- fieldNamespace: 'myForm',
106
- });
145
+ import {
146
+ useZodForm,
147
+ PartialWithAllNullables,
148
+ } from "@zod-utils/react-hook-form";
149
+ import { z } from "zod";
107
150
 
108
151
  const schema = z.object({
109
- username: z.string(),
152
+ username: z.string().min(3),
110
153
  email: z.string().email(),
154
+ age: z.number(),
111
155
  });
112
156
 
113
- // Use with Zod
114
- schema.parse({ username: '', email: 'invalid' }, { errorMap });
115
- ```
157
+ // Option 1: Use PartialWithAllNullables to make ALL fields accept null
158
+ const form = useZodForm<
159
+ z.infer<typeof schema>,
160
+ PartialWithAllNullables<z.infer<typeof schema>>
161
+ >({
162
+ schema,
163
+ defaultValues: { username: null, email: null, age: null },
164
+ });
116
165
 
117
- **Supported error types:**
118
- - `too_small` / `too_big` - With field-specific messages
119
- - `invalid_type` - Type mismatch errors
120
- - `invalid_format` - Email, URL, UUID, etc.
121
- - `invalid_value` - Enum/literal errors
122
- - And more...
166
+ // Option 2: Specify exact input types per field
167
+ const form2 = useZodForm<
168
+ z.infer<typeof schema>,
169
+ {
170
+ username?: string | null; // Can be set to null
171
+ email?: string; // Can only be undefined
172
+ age?: number | null; // Can be set to null
173
+ }
174
+ >({
175
+ schema,
176
+ defaultValues: { username: null, email: undefined, age: null },
177
+ });
178
+ ```
123
179
 
124
180
  ---
125
181
 
126
- ### `FieldNamespaceMapping`
182
+ ## Core Utilities (Re-exported)
127
183
 
128
- Mapping object for custom field names in error messages.
184
+ All utilities from `@zod-utils/core` are re-exported for convenience:
129
185
 
130
186
  ```typescript
131
- export const FieldNamespaceMapping = {
132
- department: {
133
- groupName: '部署・店舗名',
134
- },
135
- // Add your own namespaces
136
- };
187
+ import {
188
+ // Schema utilities (from @zod-utils/core)
189
+ getSchemaDefaults,
190
+ requiresValidInput,
191
+ getPrimitiveType,
192
+ removeDefault,
193
+ extractDefault,
194
+ type Simplify,
137
195
 
138
- export type FIELD_NAMESPACE = keyof typeof FieldNamespaceMapping;
196
+ // Type utilities (react-hook-form specific)
197
+ type PartialWithNullableObjects,
198
+ type PartialWithAllNullables,
199
+ } from "@zod-utils/react-hook-form";
139
200
  ```
140
201
 
141
- **Extend it:**
202
+ See [@zod-utils/core documentation](../core/README.md) for details on schema utilities.
203
+
204
+ ### Type Utilities
205
+
206
+ #### `PartialWithNullableObjects<T>`
207
+
208
+ Transforms properties based on their type. Primitive and array fields become optional-only (not nullable), while object fields become optional and nullable.
209
+
210
+ **Transformation rules:**
211
+
212
+ - **Primitives** (string, number, boolean): optional → `type | undefined`
213
+ - **Arrays**: optional → `type[] | undefined`
214
+ - **Objects**: optional and nullable → `type | null | undefined`
215
+
142
216
  ```typescript
143
- import { FieldNamespaceMapping } from '@zod-utils/react-hook-form';
144
-
145
- const CustomMapping = {
146
- ...FieldNamespaceMapping,
147
- userForm: {
148
- firstName: '名',
149
- lastName: '姓',
150
- },
217
+ import type { PartialWithNullableObjects } from "@zod-utils/react-hook-form";
218
+
219
+ type User = {
220
+ name: string;
221
+ age: number;
222
+ tags: string[];
223
+ profile: { bio: string };
151
224
  };
225
+
226
+ type FormInput = PartialWithNullableObjects<User>;
227
+ // {
228
+ // name?: string; // Primitive: optional, not nullable
229
+ // age?: number; // Primitive: optional, not nullable
230
+ // tags?: string[]; // Array: optional, not nullable
231
+ // profile?: { bio: string } | null; // Object: optional AND nullable
232
+ // }
152
233
  ```
153
234
 
154
- ---
235
+ This type is used internally by `useZodForm` to allow form fields to accept undefined (and null for objects only) during editing while maintaining proper validation types.
155
236
 
156
- ## Core Utilities (Re-exported)
237
+ #### `PartialWithAllNullables<T>`
157
238
 
158
- All utilities from `@zod-utils/core` are re-exported for convenience:
239
+ Makes all fields optional and nullable, regardless of type.
240
+
241
+ **Transformation rules:**
242
+
243
+ - **All fields**: optional and nullable → `type | null | undefined`
159
244
 
160
245
  ```typescript
161
- import {
162
- // Schema utilities
163
- getSchemaDefaults,
164
- checkIfFieldIsRequired,
165
- getPrimitiveType,
166
- removeDefault,
167
- extractDefault,
168
- getUnwrappedType,
246
+ import type { PartialWithAllNullables } from "@zod-utils/react-hook-form";
169
247
 
170
- // Type utilities
171
- type MakeOptionalAndNullable,
172
- type Simplify,
173
- type PickArrayObject,
174
- } from '@zod-utils/react-hook-form';
248
+ type User = {
249
+ name: string;
250
+ age: number;
251
+ tags: string[];
252
+ };
253
+
254
+ type FormInput = PartialWithAllNullables<User>;
255
+ // {
256
+ // name?: string | null; // All fields: optional AND nullable
257
+ // age?: number | null; // All fields: optional AND nullable
258
+ // tags?: string[] | null; // All fields: optional AND nullable
259
+ // }
175
260
  ```
176
261
 
177
- See [@zod-utils/core documentation](../core/README.md) for details.
262
+ Use this when all fields need to accept `null`, not just objects/arrays.
178
263
 
179
264
  ---
180
265
 
181
266
  ## Complete Example
182
267
 
183
268
  ```typescript
184
- import { useZodForm, getSchemaDefaults } from '@zod-utils/react-hook-form';
185
- import { z } from 'zod';
269
+ import { useZodForm, getSchemaDefaults } from "@zod-utils/react-hook-form";
270
+ import { z } from "zod";
186
271
 
187
272
  const userSchema = z.object({
188
273
  profile: z.object({
189
- firstName: z.string().min(1, 'First name is required'),
190
- lastName: z.string().min(1, 'Last name is required'),
274
+ firstName: z.string().min(1, "First name is required"),
275
+ lastName: z.string().min(1, "Last name is required"),
191
276
  age: z.number().min(18).max(120),
192
277
  }),
193
278
  contact: z.object({
@@ -195,7 +280,7 @@ const userSchema = z.object({
195
280
  phone: z.string().optional(),
196
281
  }),
197
282
  preferences: z.object({
198
- theme: z.enum(['light', 'dark']).default('light'),
283
+ theme: z.enum(["light", "dark"]).default("light"),
199
284
  notifications: z.boolean().default(true),
200
285
  }),
201
286
  });
@@ -207,44 +292,47 @@ function UserForm() {
207
292
  });
208
293
 
209
294
  const onSubmit = form.handleSubmit((data) => {
210
- console.log('Valid data:', data);
295
+ console.log("Valid data:", data);
211
296
  });
212
297
 
213
298
  return (
214
299
  <form onSubmit={onSubmit}>
215
300
  {/* Profile */}
216
- <input {...form.register('profile.firstName')} />
301
+ <input {...form.register("profile.firstName")} />
217
302
  {form.formState.errors.profile?.firstName && (
218
303
  <span>{form.formState.errors.profile.firstName.message}</span>
219
304
  )}
220
305
 
221
- <input {...form.register('profile.lastName')} />
306
+ <input {...form.register("profile.lastName")} />
222
307
  {form.formState.errors.profile?.lastName && (
223
308
  <span>{form.formState.errors.profile.lastName.message}</span>
224
309
  )}
225
310
 
226
- <input {...form.register('profile.age', { valueAsNumber: true })} type="number" />
311
+ <input
312
+ {...form.register("profile.age", { valueAsNumber: true })}
313
+ type="number"
314
+ />
227
315
  {form.formState.errors.profile?.age && (
228
316
  <span>{form.formState.errors.profile.age.message}</span>
229
317
  )}
230
318
 
231
319
  {/* Contact */}
232
- <input {...form.register('contact.email')} type="email" />
320
+ <input {...form.register("contact.email")} type="email" />
233
321
  {form.formState.errors.contact?.email && (
234
322
  <span>{form.formState.errors.contact.email.message}</span>
235
323
  )}
236
324
 
237
- <input {...form.register('contact.phone')} type="tel" />
325
+ <input {...form.register("contact.phone")} type="tel" />
238
326
 
239
327
  {/* Preferences - pre-filled with defaults */}
240
- <select {...form.register('preferences.theme')}>
328
+ <select {...form.register("preferences.theme")}>
241
329
  <option value="light">Light</option>
242
330
  <option value="dark">Dark</option>
243
331
  </select>
244
332
 
245
333
  <label>
246
334
  <input
247
- {...form.register('preferences.notifications')}
335
+ {...form.register("preferences.notifications")}
248
336
  type="checkbox"
249
337
  />
250
338
  Enable notifications
@@ -269,10 +357,10 @@ const form = useZodForm({
269
357
  });
270
358
 
271
359
  // ✅ Fully typed
272
- form.register('profile.firstName');
360
+ form.register("profile.firstName");
273
361
 
274
362
  // ❌ TypeScript error
275
- form.register('nonexistent.field');
363
+ form.register("nonexistent.field");
276
364
  ```
277
365
 
278
366
  ---
package/dist/index.d.mts CHANGED
@@ -1,66 +1,194 @@
1
+ export * from '@zod-utils/core';
1
2
  import * as react_hook_form from 'react-hook-form';
2
3
  import { FieldValues, DefaultValues, UseFormProps } from 'react-hook-form';
3
4
  import { zodResolver } from '@hookform/resolvers/zod';
4
- import { MakeOptionalAndNullable } from '@zod-utils/core';
5
- export * from '@zod-utils/core';
6
- import { ZodTypeAny, ZodErrorMap } from 'zod';
5
+ import { z } from 'zod';
6
+
7
+ /**
8
+ * Helper type that adds `null` to object-type fields only (excludes arrays).
9
+ * @internal
10
+ */
11
+ type AddNullToObjects<T> = {
12
+ [K in keyof T]: T[K] extends readonly unknown[] ? T[K] : T[K] extends object ? T[K] | null : T[K];
13
+ };
14
+ /**
15
+ * Transforms Zod schema types for form inputs.
16
+ *
17
+ * - **Primitives** (string, number, boolean): optional → `type | undefined`
18
+ * - **Arrays**: optional → `type[] | undefined`
19
+ * - **Objects**: optional and nullable → `type | null | undefined`
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * type User = { name: string; tags: string[]; profile: { bio: string } };
24
+ * type FormInput = PartialWithNullableObjects<User>;
25
+ * // { name?: string; tags?: string[]; profile?: { bio: string } | null; }
26
+ * ```
27
+ */
28
+ type PartialWithNullableObjects<T> = Partial<AddNullToObjects<T>>;
29
+ /**
30
+ * Makes all fields optional and nullable.
31
+ *
32
+ * - **All fields**: optional and nullable → `type | null | undefined`
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * type User = { name: string; age: number; tags: string[] };
37
+ * type FormInput = PartialWithAllNullables<User>;
38
+ * // { name?: string | null; age?: number | null; tags?: string[] | null; }
39
+ * ```
40
+ */
41
+ type PartialWithAllNullables<T> = {
42
+ [K in keyof T]?: T[K] | null;
43
+ };
7
44
 
8
45
  /**
9
- * Type-safe wrapper around useForm with Zod v4 schema integration
10
- * Automatically sets up zodResolver and provides better type inference
46
+ * Type-safe React Hook Form wrapper with automatic Zod v4 schema validation and type transformation.
47
+ *
48
+ * This hook eliminates the TypeScript friction between React Hook Form's nullable field values
49
+ * and Zod's strict output types. It uses a two-type schema pattern where:
50
+ * - **Input type** (`PartialWithNullableObjects<T>`): Form fields accept `null | undefined` during editing
51
+ * - **Output type** (`T`): Validated data matches exact schema type (no `null | undefined`)
52
+ *
53
+ * **Key Benefits:**
54
+ * - ✅ No more "Type 'null' is not assignable to..." TypeScript errors
55
+ * - ✅ Use `form.setValue()` and `form.reset()` with `null` values freely
56
+ * - ✅ Validated output is still type-safe with exact Zod schema types
57
+ * - ✅ Automatic zodResolver setup - no manual configuration needed
58
+ *
59
+ * @template T - The Zod schema output type (extends FieldValues)
60
+ *
61
+ * @param options - Configuration object
62
+ * @param options.schema - Zod schema with two-type signature `z.ZodType<T, PartialWithNullableObjects<T>>`
63
+ * @param options.defaultValues - Default form values (accepts nullable/undefined values)
64
+ * @param options.zodResolverOptions - Optional zodResolver configuration
65
+ * @param options....formOptions - All other react-hook-form useForm options
66
+ *
67
+ * @returns React Hook Form instance with type-safe methods
11
68
  *
12
69
  * @example
13
- * ```ts
70
+ * Basic usage with required fields
71
+ * ```typescript
72
+ * import { useZodForm } from '@zod-utils/react-hook-form';
73
+ * import { z } from 'zod';
74
+ *
14
75
  * const schema = z.object({
15
- * name: z.string(),
16
- * age: z.number()
76
+ * name: z.string().min(1), // Required field
77
+ * age: z.number().min(0),
78
+ * }) satisfies z.ZodType<{ name: string; age: number }, any>;
79
+ *
80
+ * function MyForm() {
81
+ * const form = useZodForm({ schema });
82
+ *
83
+ * // ✅ These work without type errors:
84
+ * form.setValue('name', null); // Accepts null during editing
85
+ * form.reset({ name: null, age: null }); // Reset with null
86
+ *
87
+ * const onSubmit = (data: { name: string; age: number }) => {
88
+ * // ✅ data is exact type - no null | undefined
89
+ * console.log(data.name.toUpperCase()); // Safe to use string methods
90
+ * };
91
+ *
92
+ * return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>;
93
+ * }
94
+ * ```
95
+ *
96
+ * @example
97
+ * With default values
98
+ * ```typescript
99
+ * const schema = z.object({
100
+ * username: z.string(),
101
+ * email: z.string().email(),
102
+ * notifications: z.boolean().default(true),
103
+ * }) satisfies z.ZodType<{
104
+ * username: string;
105
+ * email: string;
106
+ * notifications: boolean;
107
+ * }, any>;
108
+ *
109
+ * const form = useZodForm({
110
+ * schema,
111
+ * defaultValues: {
112
+ * username: '',
113
+ * email: '',
114
+ * // notifications gets default from schema
115
+ * },
17
116
  * });
117
+ * ```
118
+ *
119
+ * @example
120
+ * With optional and nullable fields
121
+ * ```typescript
122
+ * const schema = z.object({
123
+ * title: z.string(),
124
+ * description: z.string().optional(), // Optional in output
125
+ * tags: z.array(z.string()).nullable(), // Nullable in output
126
+ * }) satisfies z.ZodType<{
127
+ * title: string;
128
+ * description?: string;
129
+ * tags: string[] | null;
130
+ * }, any>;
18
131
  *
132
+ * const form = useZodForm({ schema });
133
+ *
134
+ * // All fields accept null/undefined during editing
135
+ * form.setValue('title', null);
136
+ * form.setValue('description', undefined);
137
+ * form.setValue('tags', null);
138
+ * ```
139
+ *
140
+ * @example
141
+ * With zodResolver options
142
+ * ```typescript
19
143
  * const form = useZodForm({
20
144
  * schema,
21
- * defaultValues: { name: '', age: 0 }
145
+ * zodResolverOptions: {
146
+ * async: true, // Enable async validation
147
+ * errorMap: customErrorMap, // Custom error messages
148
+ * },
22
149
  * });
23
150
  * ```
151
+ *
152
+ * @example
153
+ * Complete form example
154
+ * ```typescript
155
+ * const userSchema = z.object({
156
+ * name: z.string().min(1, 'Name is required'),
157
+ * email: z.string().email('Invalid email'),
158
+ * age: z.number().min(18, 'Must be 18+'),
159
+ * }) satisfies z.ZodType<{ name: string; email: string; age: number }, any>;
160
+ *
161
+ * function UserForm() {
162
+ * const form = useZodForm({
163
+ * schema: userSchema,
164
+ * defaultValues: { name: '', email: '', age: null },
165
+ * });
166
+ *
167
+ * const onSubmit = (data: { name: string; email: string; age: number }) => {
168
+ * // Type-safe: data has exact types, no null/undefined
169
+ * console.log(`${data.name} is ${data.age} years old`);
170
+ * };
171
+ *
172
+ * return (
173
+ * <form onSubmit={form.handleSubmit(onSubmit)}>
174
+ * <input {...form.register('name')} />
175
+ * <input {...form.register('email')} type="email" />
176
+ * <input {...form.register('age', { valueAsNumber: true })} type="number" />
177
+ * <button type="submit">Submit</button>
178
+ * </form>
179
+ * );
180
+ * }
181
+ * ```
182
+ *
183
+ * @see {@link PartialWithNullableObjects} for the type transformation utility
184
+ * @see https://react-hook-form.com/docs/useform for React Hook Form documentation
185
+ * @see https://zod.dev for Zod schema documentation
186
+ * @since 0.1.0
24
187
  */
25
- declare const useZodForm: <T extends FieldValues>({ schema, zodResolverOptions, ...formOptions }: {
26
- schema: ZodTypeAny;
27
- defaultValues?: DefaultValues<MakeOptionalAndNullable<T>>;
188
+ declare const useZodForm: <T extends FieldValues, I extends PartialWithAllNullables<T> = PartialWithNullableObjects<T>>({ schema, zodResolverOptions, ...formOptions }: {
189
+ schema: z.ZodType<T, I>;
190
+ defaultValues?: DefaultValues<I>;
28
191
  zodResolverOptions?: Parameters<typeof zodResolver>[1];
29
- } & Omit<UseFormProps<MakeOptionalAndNullable<T>, unknown, T>, "resolver" | "defaultValues">) => react_hook_form.UseFormReturn<any, unknown, any>;
30
-
31
- /**
32
- * Japanese error map for Zod validation errors
33
- * @param fieldName - Optional custom field name to use in error messages
34
- * @returns Zod error map function
35
- */
36
- declare function createJapaneseErrorMap(fieldName?: string): (issue: Parameters<ZodErrorMap>[0]) => string;
37
-
38
- /**
39
- * English error map for Zod validation errors
40
- * @param fieldName - Optional custom field name to use in error messages
41
- * @returns Zod error map function
42
- */
43
- declare function createEnglishErrorMap(fieldName?: string): (issue: Parameters<ZodErrorMap>[0]) => string;
44
-
45
- /**
46
- * Field namespace mapping for custom error messages
47
- * You can extend this mapping to customize field names in error messages
48
- */
49
- declare const FieldNamespaceMapping: {
50
- department: {
51
- groupName: string;
52
- };
53
- };
54
- type FIELD_NAMESPACE = keyof typeof FieldNamespaceMapping;
55
- /**
56
- * Custom error resolver with field namespace support (Japanese locale)
57
- * @deprecated Use createJapaneseErrorMap or createEnglishErrorMap instead
58
- * @param options - Configuration options
59
- * @param options.fieldNamespace - Namespace for field name mappings
60
- * @returns Error resolver function
61
- */
62
- declare const customErrorResolver: ({ fieldNamespace, }: {
63
- fieldNamespace: FIELD_NAMESPACE;
64
- }) => (issue: Parameters<ZodErrorMap>[0]) => string;
192
+ } & Omit<UseFormProps<I, unknown, T>, "resolver" | "defaultValues">) => react_hook_form.UseFormReturn<I, unknown, T>;
65
193
 
66
- export { type FIELD_NAMESPACE, FieldNamespaceMapping, createEnglishErrorMap, createJapaneseErrorMap, customErrorResolver, useZodForm };
194
+ export { type PartialWithAllNullables, type PartialWithNullableObjects, useZodForm };