@abyrd9/zod-form-data
Version:
A Zod-based form data validation library
56 lines (51 loc) • 3.66 kB
text/typescript
import { z } from 'zod/v4';
type DeepPartial<T> = T extends object ? {
[P in keyof T]?: DeepPartial<T[P]> | null;
} : T;
type ZodFormSchema = z.ZodTypeAny;
type FieldProps<T> = {
name: string;
value: T;
onChange: (payload: T) => void;
error: string | null;
};
type NestedFields<T extends z.ZodTypeAny> = T extends z.ZodObject<infer Shape> ? {
[K in keyof Shape]: NestedFields<Shape[K] & z.ZodTypeAny>;
} : T extends z.ZodRecord<any, infer Value> ? Record<string, NestedFields<Value & z.ZodTypeAny>> : T extends z.ZodMap<infer Key, infer Value> ? Map<z.infer<Key>, NestedFields<Value & z.ZodTypeAny>> : T extends z.ZodArray<infer Item> ? NestedFields<Item & z.ZodTypeAny>[] : T extends z.ZodSet<infer Item> ? Set<NestedFields<Item & z.ZodTypeAny>> : T extends z.ZodTuple<infer Items> ? {
[K in keyof Items]: NestedFields<Items[K] & z.ZodTypeAny>;
} : FieldProps<z.infer<T>>;
type NestedFieldErrors<T extends z.ZodTypeAny> = T extends z.ZodObject<infer Shape> ? {
[K in keyof Shape]: NestedFieldErrors<Shape[K] & z.ZodTypeAny>;
} : T extends z.ZodRecord<any, infer Value> ? Record<string, NestedFieldErrors<Value & z.ZodTypeAny>> : T extends z.ZodMap<infer Key, infer Value> ? Map<z.infer<Key>, NestedFieldErrors<Value & z.ZodTypeAny>> : T extends z.ZodArray<infer Item> ? NestedFieldErrors<Item & z.ZodTypeAny>[] : T extends z.ZodSet<infer Item> ? Set<NestedFieldErrors<Item & z.ZodTypeAny>> : T extends z.ZodTuple<infer Items> ? {
[K in keyof Items]: NestedFieldErrors<Items[K] & z.ZodTypeAny>;
} : string;
type ArrayElementType<Schema extends z.ZodTypeAny, Path extends string> = Path extends `${infer Key}.#.${infer Rest}` ? Schema extends z.ZodObject<infer Shape> ? Key extends keyof Shape ? Shape[Key] extends z.ZodArray<infer Item> ? ArrayElementType<Item & z.ZodTypeAny, Rest> : never : never : never : Path extends `${infer Key}.${infer Rest}` ? Schema extends z.ZodObject<infer Shape> ? Key extends keyof Shape ? ArrayElementType<Shape[Key] & z.ZodTypeAny, Rest> : never : never : Schema extends z.ZodObject<infer Shape> ? Path extends keyof Shape ? Shape[Path] extends z.ZodArray<infer Item> ? z.infer<Item> : never : never : never;
type ArrayPaths<T extends z.ZodTypeAny, Prefix extends string = ""> = T extends z.ZodObject<infer Shape> ? {
[K in keyof Shape]: Shape[K] extends z.ZodArray<infer Item> ? `${Prefix}${K & string}` | ArrayPaths<Item & z.ZodTypeAny, `${Prefix}${K & string}.#.`> : Shape[K] extends z.ZodObject<any> ? ArrayPaths<Shape[K], `${Prefix}${K & string}.`> : never;
}[keyof Shape] : never;
declare const useZodForm: <Schema extends ZodFormSchema>({ schema, defaultValues, errors: passedInErrors, }: {
schema: Schema;
defaultValues?: DeepPartial<z.infer<Schema>>;
errors?: DeepPartial<NestedFieldErrors<Schema>> | null;
}) => {
fields: NestedFields<Schema>;
getFieldArrayHelpers: <P extends ArrayPaths<Schema>>(path: P) => {
add: (value: ArrayElementType<Schema, P>) => void;
remove: (index: number) => void;
};
setFieldErrors: (newErrors: DeepPartial<NestedFieldErrors<Schema>>) => void;
};
type ParseResult<T extends ZodFormSchema> = {
success: true;
data: z.infer<T>;
} | {
success: false;
errors: DeepPartial<NestedFieldErrors<T>> | Record<string, string>;
};
declare const parseZodFormData: <T extends ZodFormSchema>(form: FormData, { schema, }: {
schema: T;
}) => ParseResult<T>;
declare const parseZodData: <T extends ZodFormSchema>(data: z.infer<T>, { schema, }: {
schema: T;
}) => ParseResult<T>;
export { type NestedFieldErrors as FieldErrors, type FieldProps, parseZodData, parseZodFormData, useZodForm };