Skip to content

Instantly share code, notes, and snippets.

@ScriptRaccoon
Last active March 13, 2025 13:42
Show Gist options
  • Save ScriptRaccoon/b8df260fcc575a115c1a84a8f8460033 to your computer and use it in GitHub Desktop.
Save ScriptRaccoon/b8df260fcc575a115c1a84a8f8460033 to your computer and use it in GitHub Desktop.
zod example
import { z } from "zod"
// USER
const userNameSchema = z
.string({
invalid_type_error: "Username must be a string",
required_error: "Username is required",
})
.min(2, { message: "Username must be at least 2 characters long" })
.refine((name) => !name.includes(" "), {
message: "Username must not contain spaces",
})
.refine((name) => name != "admin", { message: "Username cannot be admin" })
const passwordSchema = z
.string({
required_error: "Password is required",
})
.min(6, { message: "Password must be at least 6 characters long" })
.regex(/\d/, { message: "Password must contain at least one digit" })
.regex(/[a-zA-Z]/, { message: "Password must contain at least one letter" })
.regex(/[!@#$%^&*(),.?":{}|<>]/, {
message: "Password needs to have at least one special character.",
})
const addressSchema = z.object({
street: z.string().nonempty(),
city: z.string().nonempty(),
zip: z.union([z.string(), z.number()]).transform((val) => String(val)),
})
const userSchema = z.object({
username: userNameSchema,
password: passwordSchema,
email: z.string().email(),
newsletter: z.boolean().default(false),
plan: z.enum(["free", "pro", "premium"]).default("free"),
age: z.number().min(0).max(200).optional(),
interests: z.array(z.string().nonempty()).max(100).default([]),
website: z
.string()
.url({
message: "Website must be a valid URL",
})
.optional(),
address: addressSchema.optional(),
})
type User = z.infer<typeof userSchema>
const validUser = {
username: "john_doe",
password: "01a224@123",
email: "[email protected]",
interests: ["coding", "cycling"],
address: {
street: "123 Main St",
city: "Springfield",
zip: 12345,
},
}
const { data, error } = userSchema.safeParse(validUser)
if (error) {
error.errors.forEach((e) => {
console.info(e.message)
})
} else {
console.info(data)
}
// TODOS
const TodoSchema = z.object({
id: z.string().nonempty(),
text: z.string().nonempty(),
done: z.boolean().default(false),
})
const TodosSchema = z.array(TodoSchema)
type Todo = z.infer<typeof TodoSchema>
const localStorageMock = {
getItem: (key: string) =>
key === "todos" ? `[{"id":"123","text":"fix code","done":false}]` : null,
}
function get_todos(): Todo[] {
let todos: unknown = undefined
try {
const todos_string = localStorageMock.getItem("todos")
if (!todos_string) return []
todos = JSON.parse(todos_string)
} catch {
console.error("Invalid JSON data")
}
const { data, success } = TodosSchema.safeParse(todos)
if (!success) {
console.error("Invalid todos")
return []
}
return data
}
const todos = get_todos()
console.info(todos)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment