Prompt
When adding/maintaining API validation schemas, make the input contract explicit: specify exactly what input types are accepted, and whether the schema is parsing (strict mapping) or coercing/converting values. Don’t rely on assumptions about built-in JS semantics or on a single runtime’s concrete types.
Apply these rules:
- Boolean: If the API accepts boolean-like strings, confirm the semantics.
z.string().boolean()does not matchBoolean()/MDN behavior—usez.coerce.boolean()when you want JSBoolean()-style coercion. - Dates: Use
z.date()only for actualDateobjects. If the API accepts date strings too, explicitly convert viaz.preprocess. - Cross-runtime files: Don’t couple validation to “browser File only” if your API is used in Node/Deno too. Validate a shared file contract (e.g.,
size,type, etc.) or create separate schemas per runtime. - Deprecations: Avoid deprecated Zod helpers in public schemas; use current equivalents (e.g.,
z.string().min(1)instead of deprecatednonempty).
Example (date + boolean semantics):
import { z } from "zod";
// Dates: accept both Date and ISO strings
const dateSchema = z.preprocess((arg) => {
if (typeof arg === "string" || arg instanceof Date) return new Date(arg);
}, z.date());
// Booleans: choose semantics explicitly
const strictLogicalBool = z.string().boolean(); // accepts specific strings like "TRUE"/"False"
const jsBooleanLike = z.coerce.boolean(); // matches JS Boolean() coercion semantics