typescript - Cum să obții forma unui schema în zod atunci când folosești superRefine?
Pentru un schemă zod simplă ca aceasta
const schema = z
.object({
name: z.string(),
age: z.number()
})
Am acest cod care merge bine:
export const handleForm =
(schema: z.AnyZodObject) =>
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
const keys = Object.keys(schema.shape) as unknown as Array<keyof z.infer<typeof schema>>;
const arrayKeys = keys.filter(key => schema.shape[key] instanceof z.ZodArray);
const values = Object.fromEntries(
Array.from(data.keys()).map(key => [key, arrayKeys.includes(key) ? data.getAll(key) : data.get(key)]),
);
Partea interesantă la asta este că putem introspecta schema zod, pentru a ști dacă o cheie a obiectului este un array și, dacă da, să folosim FormData.getAll în loc de get.
Acum, am câteva cazuri limită care trebuie să folosească superRefine :
const schema = z
.object({
name: z.string(),
age: z.number()
})
.superRefine( ...)
De data aceasta, schema nu este dedusă ca z.AnyZodObject, ci ca z.ZodEffects<z.AnyZodObject>.
Din păcate, acest tip nu are proprietatea shape care să poată fi introspectată.
Am văzut niște API-uri interne (_input, _output, _def), dar nu pot să-mi dau seama cum să le folosesc.
Nici eu nu înțeleg cu adevărat de ce un superRefine schimbă tipul. OK dacă folosim transform, coerce, dar credeam că superRefine era doar un mijloc de a arunca o eroare și că nu schimba tipul?
Răspuns #1
Folosind metoda: innerType() sau sourceType(): de ex: z.object({}).superRefine(()=>{}).sourceType()