typescript - Hvordan iterere over egenskaper og få typene i Zod?
Si at du har et grunnleggende system som dette i Zod:
import { z } from 'zod'
const Post = z.object({
title: z.string(),
})
const User = z.object({
name: z.string(),
email: z.string().optional(),
posts: z.array(Post),
loginCount: z.number().min(1)
})
Hvordan itererer du gjennom egenskapene og inspiserer alternativene på egenskapene?
Jeg ser at det finnes en .shape-egenskap, men hvordan gjør man dette:
for (const name in shape) {
const prop = shape[name]
if (prop.min != null) {
console.log(`Has min ${prop.min}`)
}
if (prop.max != null) {
console.log(`Has max ${prop.max}`);
}
if (prop.optional === true) {
console.log(`Is optional`);
}
if (prop.type) {
if (prop.type is array) {
prop.type.forEach(item => {
console.log(`Has array item type ${item.name}`)
})
} else if (prop.type is union) {
// ... show union type names
} else {
// show basic type name
}
}
}
Jeg trenger å bruke denne definisjonen til, for eksempel:
- Få nøklene til hvert skjema
- Få den tillatte egenskapstypen/egenskapstypene for en egenskap på et skjema (slik at jeg kan vite hvilken databord jeg skal sette inn i, for eksempel)
- Lag dokumentasjon
- Slike ting.
Jeg ser ingen dokumentasjon for ting som dette og vil ikke ende opp med å oppfinne hjulet på nytt ved å lage mitt eget bibliotek for å håndtere typer og typeinspeksjon.
Svar #1
Zod er egentlig ikke laget for å brukes slik, men avhengig av kompleksiteten til skjemaene dine, kan du komme ganske langt ved å se på kilden: https://github.com/colinhacks/zod/blob/master/src/types.ts
For eksempel kan du se at de ulike typene er klasser, og for eksempel at talltypen har minValue og maxValue getters. Så for å få tak i disse, kan du gjøre:
if (s instanceof ZodNumber)
console.log(s.minValue, s.maxValue)
Den shape du nevner er en getter på ZodObject-typen, noe som betyr at du kan gjøre:
if (s instanceof ZodObject)
for (const field of schema.shape)
// look at each field
Du vil også se at valgfrie og nullable skjemaer er klassene ZodOptional og ZodNullable, og at de begge har en unwrap()-metode for å se på de indre verdiene, noe som betyr at du kan gjøre noe som dette:
let required = true;
while (s instanceof ZodOptional || s instanceof ZodNullable) {
required = false;
s = s.unwrap();
}
Hvis du gjør forbedringer eller transformasjoner, vil de bli pakket inn i ZodEffects-klassen, og der vil du se at det finnes en innerType()-metode for å komme til den indre typen der.
I utgangspunktet trenger du bare å gå gjennom tingene rekursivt, se på hver ting, sjekke hvilken type det er, og håndtere det i henhold til ditt behov.
