Communitygithub.com

Zod Schema

Uma biblioteca opinativa de habilidades para agentes de IA.

O que é Zod Schema?

Esta habilidade fornece diretrizes opinativas e completas para usar o Zod 4 em projetos TypeScript, cobrindo desde a criação de esquemas até práticas de segurança e teste. Ela define claramente o que a camada de esquema 'possui' — forma, parsing, tipos, erros e codecs — e o que pertence a outras capacidades, como segurança de aplicação ou estado do servidor. A habilidade é estritamente direcionada ao Zod 4.4.3+, com TypeScript 5.5+ e `strict: true`, e inclui listas de detecção para identificar e substituir idioms obsoletos do Zod 3 que ainda compilam. O documento está organizado em várias seções de referência, como fronteiras de validação, módulos de esquema, uniões, transformações, codecs, parsing de formulários, e postura de segurança, fornecendo regras claras sobre onde e como aplicar cada recurso do Zod para construir sistemas robustos e de fácil manutenção.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add axross/skills

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Esquema Zod

Use esta capacidade sempre que uma alteração tocar no Zod — um esquema sendo escrito, um parse sendo colocado, um payload sendo decodificado ou um erro sendo exibido. Ela é responsável pela camada de esquema: a forma, a chamada de parse, o tipo que essa forma produz, o erro que gera e o codec que transporta dados entre um formato de transmissão e um modelo de domínio.

Ela não é responsável por quatro questões vizinhas, cada uma de responsabilidade de uma capacidade própria:

  • Se uma entrada não é confiável e, portanto, deve ser verificada — julgamento de uma capacidade de segurança de aplicação. Esta habilidade assume que esse julgamento é feito e diz como o Zod o executa.
  • Que existe um hook para o parse se inserir — um manipulador de rota, uma função de servidor, uma ação de formulário — um fato de uma capacidade de framework.
  • Quando um payload buscado é rebuscado, armazenado em cache ou invalidado — preocupação de uma capacidade de estado do servidor. Esta habilidade apenas coloca um parse dentro da função de consulta que ela possui.
  • Como um componente recebe, renderiza e é testado contra o resultado parseado — preocupação de uma capacidade de desenvolvimento de componentes.

Onde uma regra aqui tem uma contraparte em uma dessas, esta habilidade declara o mecanismo do Zod e nomeia o outro como proprietário.

Disciplina de versão. Esta habilidade é escrita apenas para Zod 4. Zod 3 está fora de escopo como uma linha suportada: sem caminho de migração, sem orientação zod/v3 e nenhuma regra declarada em sua forma Zod 3. O único lugar onde o Zod 3 aparece é como um sinal de detecção — uma lista de idioms obsoletos, para que código desatualizado possa ser reconhecido e substituído pela forma atual. Essa é uma regra do Zod 4 sobre uma base de código Zod 4, não cobertura do Zod 3. O limite importa mais aqui do que o normal, porque respostas do Zod 3 ainda superam as respostas do Zod 4 em tutoriais, postagens em fóruns e recall de modelos — e a maioria dos idioms do Zod 3 ainda compila contra uma instalação do Zod 4, então "funciona" não é evidência de que uma regra está atualizada. O Zod 4 também se move dentro de sua própria major: z.xor, z.invertCodec e o parâmetro de direção .brand chegaram após a 4.0. Cada declaração sensível à versão aqui nomeia contra o que foi verificada, e onde uma superfície é conhecida por se mover, a regra é uma consulta — consulte a documentação da versão instalada em https://zod.dev/ — em vez de um nome de API congelado. Trate uma afirmação sem versão sobre uma API do Zod, nesta habilidade ou em qualquer outro lugar, como suspeita.

Verificado contra [email protected], publicado em 2026-05-04 — https://zod.dev/ — com TypeScript 5.5+ e strict: true como pré-requisitos declarados. Cada arquivo de referência carrega sua própria linha Verificado contra com a página upstream contra a qual suas regras foram verificadas.

Fora do escopo. Zod 3 em todas as formas. A linha 4.5.0-canary, da qual nenhuma regra aqui foi derivada. Outras bibliotecas de validação, exceto onde um limite é compartilhado com uma — a interoperabilidade do Standard Schema é coberta, as APIs do Valibot ou ArkType não são. Ferramentas de geração de código que emitem esquemas Zod são nomeadas onde alteram o que você ainda deve escrever manualmente, mas sua própria configuração é delas.

As palavras-chave "DEVE", "NÃO DEVE", "REQUERIDO", "DEVERIA", "NÃO DEVERIA", "RECOMENDADO", "PODE" e "OPCIONAL" neste documento devem ser interpretadas conforme descrito em RFC 2119.

O Limite de Validação

Consulte validation-boundary.md para:

  • colocar o único parse na borda onde os dados entram e nunca re-parsear internamente a ele
  • unknown a montante do parse e z.infer<typeof Schema> a jusante, nunca uma interface escrita à mão
  • quais perguntas pertencem a uma capacidade de segurança de aplicação, framework, estado do servidor ou componente
  • os casos em que um esquema custa sem comprar — dados internos, um valor já parseado, um loop por item
  • executar o Zod ao lado de um segundo validador e converter entre eles em um lugar

Versão e Pacotes

Consulte version-and-packages.md para:

  • distinguir zod.dev (Zod 4) de v3.zod.dev (Zod 3) antes de confiar em uma página
  • escolher entre zod, zod/mini, zod/locales e os links permanentes zod/v4/*
  • o TypeScript 5.5+ assumido e strict: true, sem o qual a opcionalidade inferida é insegura
  • os pisos de versão menor para z.xor, z.invertCodec, .safeExtend, z.property e a direção .brand
  • os idioms do Zod 3 que ainda compilam contra o Zod 4, como um sinal de desatualização

Módulos de Esquema

Consulte schema-modules.md para:

  • as convenções de nomenclatura const X / type X e zX, e escolher uma por repositório
  • primitivas compartilhadas EntityId, Timestamp e NonEmptyString como o vocabulário do qual outros esquemas compõem
  • .brand<"Name">(), sua direção "out"/"in"/"inout" e as fixtures que força através de um parse
  • derivar com .shape, .extend, .safeExtend, .pick, .omit e o lançamento de .merge() 4.4 em refinamentos
  • içar cada esquema para o escopo do módulo, em vez de reconstruí-lo por requisição ou renderização

Primitivas e Formatos

Consulte primitives-and-formats.md para:

  • os métodos de nível superior z.email(), z.url(), z.uuid() e z.iso.datetime() que substituíram os métodos z.string().x()
  • escolher z.uuid() estrito em vez de z.guid() permissivo, e z.httpUrl() em vez de z.url() para uma URL buscada
  • z.stringFormat() para um formato próprio do projeto e z.templateLiteral() para um tipo de template literal
  • o intervalo de inteiro seguro de z.int(), a rejeição de Infinity e os largura fixa z.int32() e z.float64()
  • z.enum() em vez do obsoleto z.nativeEnum(), com .exclude() e .extract()

Objetos e Coleções

Consulte objects-and-collections.md para:

  • z.object() removendo chaves não modeladas, e z.strictObject(), z.looseObject() e .catchall() alterando isso
  • auto-referência através de um getter e a anotação de tipo de retorno que um erro de circularidade precisa
  • os dois argumentos obrigatórios de z.record(), chaves de enum exaustivas e z.partialRecord()
  • z.tuple() onde .nonempty() não produz mais um tipo de tupla, além de z.file() e z.json()
  • parsear um esquema de array uma vez em vez de um esquema de item por elemento

Uniões

Consulte unions.md para:

  • z.discriminatedUnion() para estreitamento, qualidade de erro e velocidade de parse em vez de uma z.union() simples
  • o discriminador literal que cada ramo deve fixar, e as uniões e pipes aninhados que o Zod 4 permite dentro de um
  • z.xor() para o caso em que um valor correspondendo a dois ramos é um defeito
  • z.intersection() lançando um Error simples em vez de um ZodError em um resultado não mesclável
  • a união de formas de campo opcional que deveriam ter sido um único objeto

Opcionalidade e Padrões

Consulte optionality-and-defaults.md para:

  • escolher .optional(), .nullable() ou .nullish() com base no que o produtor realmente emite
  • .default() fazendo curto-circuito no tipo de saída versus .prefault() parseando no tipo de entrada
  • .catch() transformando uma falha de parse em um fallback, e quando isso esconde um produtor divergente
  • .nullish().transform((v) => v ?? null) para colapsar um produtor misto de nulo e indefinido
  • o que exactOptionalPropertyTypes faz ao tipo inferido de uma propriedade opcional

Refinamentos

Consulte refinements.md para:

  • .refine(), .superRefine() e .check(), e a regra de que nenhum deles pode lançar
  • ctx.addIssue(), z.NEVER e o path que coloca um erro em um campo específico
  • abort para parar uma cadeia e when do 4.4 para pular uma verificação cujas entradas já são inválidas
  • um refinamento assíncrono forçando .parseAsync() em cada chamador existente do esquema composto
  • uma regra de permissão, cota ou unicidade pertencendo ao domínio, não ao esquema

Transformações e Pipes

Consulte transforms-and-pipes.md para:

  • .transform() após a validação, z.preprocess() antes dela e .pipe() entre dois esquemas
  • .overwrite() onde o valor muda, mas o tipo e sua introspeccionalidade não devem
  • z.input versus z.output/z.infer, e os bugs de forma e fixture de confundi-los
  • ctx.issues.push ou ctx.addIssue do 4.4 com z.NEVER para falhar de dentro de uma transformação
  • onde a remodelagem dos dados do produtor termina e uma decisão de domínio começa

Codecs

Consulte codecs.md para:

  • z.codec(input, output, { decode, encode }) para um limite que .transform() não pode reverter
  • .decode() e .encode() com suas formas safe* e *Async, além de z.invertCodec()
  • os templates documentados isoDatetimeToDate, json, stringToURL e base64ToBytes — copiados, não importados
  • padrões e .catch() aplicando apenas na decodificação, e um .transform() fazendo encode lançar um não-ZodError
  • o codec total que não pode falhar, e a garantia de forma que, portanto, não fornece

Coerção e Configuração

Consulte coercion-and-config.md para:

  • z.coerce.number().parse("") retornando 0, e z.coerce.boolean().parse("false") retornando true
  • z.stringbool() como o construto que rejeita um valor que não está nem no conjunto verdadeiro nem no falso
  • strings de consulta, dados de formulário e variáveis de ambiente como as três fontes com valor de string
  • parsear a configuração uma vez na inicialização e terminar em vez de expor undefined posteriormente
  • manter a configuração secreta fora dos logs e fora de um bundle cliente

Parsing

Consulte parsing.md para:

  • .parse() quando uma falha é um defeito, .safeParse() quando é um resultado para ramificar
  • .parseAsync() sendo obrigatório em vez de opcional assim que qualquer verificação no esquema é assíncrona
  • o clone profundo que um parse retorna, e a identidade de referência que, portanto, quebra
  • remapear ZodError para um erro de domínio para que o Zod permaneça fora das assinaturas de domínio
  • registrar o limite e os caminhos do problema, nunca a entrada que falhou

Erros

Consulte errors.md para:

  • error.issues com seu code e path, e os aliases .errors e .formErrors removidos
  • z.treeifyError(), z.flattenError() e z.prettifyError(), escolhidos pelo consumidor
  • o parâmetro unificado error que substituiu message, invalid_type_error e errorMap
  • a precedência — esquema, por parse, z.config({ customError }), localidade — que inverteu no Zod 4
  • reportInput colocando entrada não confiável em um erro que viaja para um rastreador ou um cliente

Metadados e JSON Schema

Consulte metadata-and-json-schema.md para:

  • .meta(), z.registry(), z.globalRegistry e estender GlobalMeta por declaração de mesclagem
  • vinculação de metadados a uma instância de esquema, então .optional() ou .extend() os órfãos
  • as opções target, io, unrepresentable, cycles, reused e uri de z.toJSONSchema()
  • io: "input" produzindo um documento diferente da visão de saída padrão
  • os tipos date, map, set, transform e bigint sem representação em JSON Schema

Saída Estruturada de Modelo

Consulte model-structured-output.md para:

  • um esquema como um contrato generateObject ou ferramenta, e satisfies z.ZodRawShape onde uma forma bruta é desejada
  • texto .describe() alcançando o modelo como instrução em vez de documentação
  • .nullable() sobrevivendo ao modo estrito de um provedor onde .optional() e .nullish() são rejeitados
  • reutilizar .shape.field para que a saída do modelo não possa divergir do tipo de domínio que alimenta
  • re-prompt de um ZodError sob uma repetição limitada, em vez de corrigir saída inválida

Formulários

Consulte forms.md para:

  • um resolvedor específico do Zod para detalhes de problema do próprio Zod, ou um do Standard Schema para independência de biblioteca
  • z.input para os valores e valores padrão do formulário, z.output para o manipulador de envio
  • path em um refinamento entre campos como a única forma de um erro alcançar a entrada correta
  • a string vazia que um campo numérico em branco envia, e a chave ausente que uma caixa de seleção não marcada envia
  • o re-parse no lado do servidor que um esquema do lado do cliente nunca substitui

Limites de Armazenamento de Dados

Consulte data-store-boundaries.md para:

  • a forma armazenada e o modelo de domínio como dois esquemas com uma transformação entre eles
  • metades de leitura e escrita escritas como um par, para que um campo renomeado não possa divergir entre elas
  • .partial() para um patch e .omit().extend() para uma entrada de criação carregando sentinelas de armazenamento
  • z.instanceof() para tipos próprios de um driver e z.property() para restringir um de seus campos
  • um payload variando por profundidade de consulta, estado de rascunho ou localidade — e o esquema totalmente opcional que não é a resposta

Desempenho e Pegada

Consulte performance-and-footprint.md para:

  • os ganhos de parse publicados de ~14x, ~7x e ~6.5x, e a queda de ~25.000 para ~175 instanciações de tipo
  • a API funcional de zod/mini e núcleo de 1,88 kB, e por que um servidor não deve adotá-lo
  • construção de esquema içada para fora de um caminho quente, e uma coleção parseada uma vez em vez de por item
  • .check() em vez de .refine() e uma união discriminada em vez de linear, em um caminho medido
  • z.looseObject() pulando a passagem de remoção de chave, e a proteção que isso troca

Postura de Segurança

Consulte security-posture.md para:

  • a remoção de z.object() como proteção contra atribuição em massa, e o que z.looseObject() readmite
  • um parse bem-sucedido não sendo escape HTML, parametrização SQL ou garantia de busca segura
  • .max() colocado antes de um .regex() ou um refinamento caro, para limitar o trabalho controlado por atacante
  • arrays ilimitados, profundidade de recursão ilimitada e entrada cíclica que loopa para sempre
  • um esquema de resposta com lista de permissões, sem o qual um campo privado sai com o payload

Testando Esquemas

Consulte testing-schemas.md para:

  • por que afirmar que z.email() rejeita "nope" testa o Zod em vez do esquema
  • z.input<typeof Schema> como o tipo de fixture, construído a partir de um payload observado

Habilidades Relacionadas