ワンクリックで
ghcopilot-hub-zod
Zod 4 schema validation patterns. Trigger: When using Zod for validation - breaking changes from v3.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Zod 4 schema validation patterns. Trigger: When using Zod for validation - breaking changes from v3.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | ghcopilot-hub-zod |
| description | Zod 4 schema validation patterns. Trigger: When using Zod for validation - breaking changes from v3. |
| license | Apache-2.0 |
| metadata | {"author":"jmgomezdev","version":"1.0"} |
// ❌ Zod 3 (OLD)
z.string().email();
z.string().uuid();
z.string().url();
z.string().nonempty();
z.object({ name: z.string() }).required_error("Required");
// ✅ Zod 4 (NEW)
z.email();
z.uuid();
z.url();
z.string().min(1);
z.object({ name: z.string() }, { error: "Required" });
import { z } from "zod";
// Primitives
const stringSchema = z.string();
const numberSchema = z.number();
const booleanSchema = z.boolean();
const dateSchema = z.date();
// Top-level validators (Zod 4)
const emailSchema = z.email();
const uuidSchema = z.uuid();
const urlSchema = z.url();
// With constraints
const nameSchema = z.string().min(1).max(100);
const ageSchema = z.number().int().positive().max(150);
const priceSchema = z.number().min(0).multipleOf(0.01);
const userSchema = z.object({
id: z.uuid(),
email: z.email({ error: "Invalid email address" }),
name: z.string().min(1, { error: "Name is required" }),
age: z.number().int().positive().optional(),
role: z.enum(["admin", "user", "guest"]),
metadata: z.record(z.string(), z.unknown()).optional(),
});
type User = z.infer<typeof userSchema>;
// Parsing
const user = userSchema.parse(data); // Throws on error
const result = userSchema.safeParse(data); // Returns { success, data/error }
if (result.success) {
console.log(result.data);
} else {
console.log(result.error.issues);
}
// Arrays
const tagsSchema = z.array(z.string()).min(1).max(10);
const numbersSchema = z.array(z.number()).nonempty();
// Records (objects with dynamic keys)
const scoresSchema = z.record(z.string(), z.number());
// { [key: string]: number }
// Tuples
const coordinatesSchema = z.tuple([z.number(), z.number()]);
// [number, number]
// Simple union
const stringOrNumber = z.union([z.string(), z.number()]);
// Discriminated union (more efficient)
const resultSchema = z.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.unknown() }),
z.object({ status: z.literal("error"), error: z.string() }),
]);
// Transform during parsing
const lowercaseEmail = z.email().transform((email) => email.toLowerCase());
// Coercion (convert types)
const numberFromString = z.coerce.number(); // "42" → 42
const dateFromString = z.coerce.date(); // "2024-01-01" → Date
// Preprocessing
const trimmedString = z.preprocess(
(val) => (typeof val === "string" ? val.trim() : val),
z.string()
);
const passwordSchema = z
.string()
.min(8)
.refine((val) => /[A-Z]/.test(val), {
message: "Must contain uppercase letter",
})
.refine((val) => /[0-9]/.test(val), {
message: "Must contain number",
});
// With superRefine for multiple errors
const formSchema = z
.object({
password: z.string(),
confirmPassword: z.string(),
})
.superRefine((data, ctx) => {
if (data.password !== data.confirmPassword) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Passwords don't match",
path: ["confirmPassword"],
});
}
});
// Optional (T | undefined)
z.string().optional();
// Nullable (T | null)
z.string().nullable();
// Both (T | null | undefined)
z.string().nullish();
// Default values
z.string().default("unknown");
z.number().default(() => Math.random());
// Zod 4: Use 'error' param instead of 'message'
const schema = z.object({
name: z.string({ error: "Name must be a string" }),
email: z.email({ error: "Invalid email format" }),
age: z.number().min(18, { error: "Must be 18 or older" }),
});
// Custom error map
const customSchema = z.string({
error: (issue) => {
if (issue.code === "too_small") {
return "String is too short";
}
return "Invalid string";
},
});
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
const schema = z.object({
email: z.email(),
password: z.string().min(8),
});
type FormData = z.infer<typeof schema>;
function Form() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
</form>
);
}
zod, validation, schema, typescript, forms, parsing
Next.js 16 App Router patterns for Server Components, Server Actions, route handlers, caching, streaming, and version-sensitive request APIs. Trigger: Use when working in Next.js 16 App Router code with app/, layout.tsx, page.tsx, loading.tsx, generateMetadata, Server Actions, route.ts handlers, revalidatePath/revalidateTag, cookies()/headers()/params async APIs, middleware.ts vs proxy.ts naming, or RSC streaming and serialization issues.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
React 19 patterns with Compiler-aware guidance, composition, refs, and effects. Trigger: When working with React components (.tsx, .jsx), effects, refs, context APIs, or render performance/memoization decisions.
Layer-aware testing strategies for Clean Architecture using Vitest, React Testing Library, MSW, and Cypress. Use when creating or reviewing unit, integration, component, architectural, or E2E test plans across `src/domain`, `src/application`, `src/infrastructure`, `src/interface`, and `src/presentation`, especially for mocking-boundary decisions, async reliability, and flaky-test prevention. Trigger keywords: test, vitest, cypress, e2e, mock, msw, renderHook, loader, query, router, zustand.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Advanced TypeScript decision patterns for strict typing: satisfies vs type annotations, exhaustiveness checks, const-derived unions, and performance-aware control/data flow. Trigger: Use when the task involves TypeScript modeling decisions (type vs interface, enum alternatives), strict mode/type errors, generics, utility types, or hot-path performance issues in branching/looping.