zod-validation-utilities

安装量: 73
排名: #10569

安装

npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill zod-validation-utilities

Zod Validation Utilities Overview Production-ready Zod v4 patterns for reusable, type-safe validation with minimal boilerplate. Focuses on modern APIs, predictable error handling, and form integration. When to Use Defining request/response validation schemas in TypeScript services Parsing untrusted input from APIs, forms, env vars, or external systems Standardizing coercion, transforms, and cross-field validation Building reusable schema utilities across teams Integrating React Hook Form with Zod using zodResolver Instructions Start with strict object schemas and explicit field constraints Prefer modern Zod v4 APIs and the error option for error messages Use coercion at boundaries ( z.coerce.* ) when input types are uncertain Keep business invariants in refine / superRefine close to schema definitions Export both schema and inferred types ( z.input / z.output ) for consistency Reuse utility schemas (email, id, dates, pagination) to reduce duplication Examples 1) Modern Zod 4 primitives and object errors import { z } from "zod" ; export const UserIdSchema = z . uuid ( { error : "Invalid user id" } ) ; export const EmailSchema = z . email ( { error : "Invalid email" } ) ; export const WebsiteSchema = z . url ( { error : "Invalid URL" } ) ; export const UserProfileSchema = z . object ( { id : UserIdSchema , email : EmailSchema , website : WebsiteSchema . optional ( ) , } , { error : "Invalid user profile payload" } ) ; 2) Coercion, preprocess, and transform import { z } from "zod" ; export const PaginationQuerySchema = z . object ( { page : z . coerce . number ( ) . int ( ) . min ( 1 ) . default ( 1 ) , pageSize : z . coerce . number ( ) . int ( ) . min ( 1 ) . max ( 100 ) . default ( 20 ) , includeArchived : z . coerce . boolean ( ) . default ( false ) , } ) ; export const DateFromUnknownSchema = z . preprocess ( ( value ) => ( typeof value === "string" || value instanceof Date ? value : undefined ) , z . coerce . date ( { error : "Invalid date" } ) ) ; export const NormalizedEmailSchema = z . string ( ) . trim ( ) . toLowerCase ( ) . email ( { error : "Invalid email" } ) . transform ( ( value ) => value as Lowercase < string

) ; 3) Complex schema structures import { z } from "zod" ; const TagSchema = z . string ( ) . trim ( ) . min ( 1 ) . max ( 40 ) ; export const ProductSchema = z . object ( { sku : z . string ( ) . min ( 3 ) . max ( 24 ) , tags : z . array ( TagSchema ) . max ( 15 ) , attributes : z . record ( z . string ( ) , z . union ( [ z . string ( ) , z . number ( ) , z . boolean ( ) ] ) ) , dimensions : z . tuple ( [ z . number ( ) . positive ( ) , z . number ( ) . positive ( ) , z . number ( ) . positive ( ) ] ) , } ) ; export const PaymentMethodSchema = z . discriminatedUnion ( "type" , [ z . object ( { type : z . literal ( "card" ) , last4 : z . string ( ) . regex ( / ^ \d {4} $ / ) } ) , z . object ( { type : z . literal ( "paypal" ) , email : z . email ( ) } ) , z . object ( { type : z . literal ( "wire" ) , iban : z . string ( ) . min ( 10 ) } ) , ] ) ; 4) refine and superRefine import { z } from "zod" ; export const PasswordSchema = z . string ( ) . min ( 12 ) . refine ( ( v ) => / [ A - Z ] / . test ( v ) , { error : "Must include an uppercase letter" } ) . refine ( ( v ) => / \d / . test ( v ) , { error : "Must include a number" } ) ; export const RegisterSchema = z . object ( { email : z . email ( ) , password : PasswordSchema , confirmPassword : z . string ( ) , } ) . superRefine ( ( data , ctx ) => { if ( data . password !== data . confirmPassword ) { ctx . addIssue ( { code : "custom" , path : [ "confirmPassword" ] , message : "Passwords do not match" , } ) ; } } ) ; 5) Optional, nullable, nullish, and default import { z } from "zod" ; export const UserPreferencesSchema = z . object ( { nickname : z . string ( ) . min ( 2 ) . optional ( ) , // undefined allowed bio : z . string ( ) . max ( 280 ) . nullable ( ) , // null allowed avatarUrl : z . url ( ) . nullish ( ) , // null or undefined allowed locale : z . string ( ) . default ( "en" ) , // fallback when missing } ) ; 6) React Hook Form integration ( zodResolver ) import { useForm } from "react-hook-form" ; import { zodResolver } from "@hookform/resolvers/zod" ; import { z } from "zod" ; const ProfileFormSchema = z . object ( { name : z . string ( ) . min ( 2 , { error : "Name too short" } ) , email : z . email ( { error : "Invalid email" } ) , age : z . coerce . number ( ) . int ( ) . min ( 18 ) , } ) ; type ProfileFormInput = z . input < typeof ProfileFormSchema

; type ProfileFormOutput = z . output < typeof ProfileFormSchema

; const form = useForm < ProfileFormInput , unknown , ProfileFormOutput

( { resolver : zodResolver ( ProfileFormSchema ) , criteriaMode : "all" , } ) ; Best Practices Keep schemas near boundaries (HTTP handlers, queues, config loaders) Prefer safeParse for recoverable flows; parse for fail-fast execution Share small schema utilities ( id , email , slug ) to enforce consistency Use z.input and z.output when transforms/coercions change runtime shape Avoid overusing preprocess ; prefer explicit z.coerce.* where possible Treat external payloads as untrusted and always validate before use Constraints and Warnings Ensure examples match your installed zod major version (v4 APIs shown) error is the preferred option for custom errors in Zod v4 patterns Discriminated unions require a stable discriminator key across variants Coercion can hide bad upstream data; add bounds and refinements defensively

返回排行榜