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.

Relaterte artikler