35 lines
880 B
TypeScript
35 lines
880 B
TypeScript
|
import type { z } from "zod";
|
||
|
|
||
|
type ErrorMessage = string;
|
||
|
type Errors<Schema> = Partial<Record<keyof Schema, ErrorMessage>>;
|
||
|
export type FormError<Schema extends z.Schema<unknown>> = Partial<
|
||
|
Record<keyof Schema["_type"] | "general", ErrorMessage>
|
||
|
>;
|
||
|
type ValidationResult<Data, Schema> = { data: Data; errors: undefined } | { data: undefined; errors: Errors<Schema> };
|
||
|
|
||
|
export function validate<Data, Schema = z.Schema<Data>["_type"]>(
|
||
|
schema: z.Schema<Data>,
|
||
|
value: unknown,
|
||
|
): ValidationResult<Data, Schema> {
|
||
|
const result = schema.safeParse(value);
|
||
|
if (result.success) {
|
||
|
return {
|
||
|
data: result.data,
|
||
|
errors: undefined,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const errors: Errors<Schema> = {};
|
||
|
result.error.issues.forEach((error) => {
|
||
|
const path = error.path[0] as keyof Schema;
|
||
|
if (!errors[path]) {
|
||
|
errors[path] = error.message;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return {
|
||
|
data: undefined,
|
||
|
errors,
|
||
|
};
|
||
|
}
|