5.1 validateSchema
5.1 validateSchema
We beginnen met een eenvoudige functie die een Zod schema valideert en de verwerkte data of eventuele validatiefouten teruggeeft.
Aangezien de functie zowel fouten als de verwerkte data kan teruggeven moet het returntype dit ook beschrijven. We definiëren hiervoor een type met twee properties, errors en data, waar we voor beide properties een null waarde toestaan. Omdat we niet weten wat voor soort object teruggegeven wordt door de validatiefunctie gebruiken we een generische parameter voor de data property.
type ValidationResult<T> = { data: T | null; errors: Record<string, string[] | undefined> | null }Alhoewel het bovenstaande werkt, moeten we voor de returnwaarde altijd controleren of de properties null zijn voor we deze gebruiken. We kunnen het type nog optimaliseren door de twee mogelijkheden expliciet te maken. Ofwel zijn er errors, ofwel is er data, maar het resultaat bevat nooit een waarde voor beide properties. Door het returntype een unie van deze twee mogelijkheden te maken, weet TypeScript dat de data property gedefinieerd is als de errors null zijn en omgekeerd.
type ValidationResult<T> =
| {data: null; errors: Record<string, string[] | undefined>}
| {data: T; errors: null}Als laatste optimalisatie kunnen we de generische parameter T nog meer specifiëren, we weten dat het validatieresultaat altijd afgeleid is van een zod schema. Door de generische parameter aan te passen naar iets dat overerft van ZodType (eender welk zod schema) en door het type van de data property aan te passen naar het afgeleide object dat door een zod schema terugegeven wordt, maken we dit expliciet.
import type {ZodType} from 'zod/v4'
import {z} from 'zod/v4'
type ValidationResult<Schema extends ZodType> =
| {data: null; errors: Record<string, string[] | undefined>}
| {data: z.infer<Schema>; errors: null}Nu dat het returntype gedefinieerd is, kunnen de functie implementeren. De functie neemt een Zod schema en een object van een onbekend type als argument en geeft ofwel de errors, ofwel de verwerkte data terug. Als het object van het type FormData is, wordt het omgevormd naar een object via de convertFormData functie die we in appendix 3 besproken hebben, anders wordt het object rechtstreeks doorgegeven aan de safeParse functie. Aangezien we niet weten wat voor soort schema het Zod schema is, gebruiken we opnieuw een generische parameter om het type van het schema aan te duiden.
export function validateSchema<Schema extends ZodType>(schema: Schema, data: unknown): ValidationResult<Schema> {
// In case z.void() was used as schema, the type of the data argument is function.
// To successfully validate the data, we need to convert it to undefined.
const result = schema.safeParse(
data instanceof FormData ? convertFormData(data) : typeof data === 'function' ? undefined : data,
)
return result.success
? {data: result.data as z.infer<Schema>, errors: null}
: {data: null, errors: z.flattenError(result.error).fieldErrors}
}