parse vs safeParse
Handle validation success and failure gracefully.
parse vs safeParse is a free TypeScript Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Two Ways to Validate
Zod gives you two validation methods: parse, which throws on invalid data, and safeParse, which returns a result object instead.
import { z } from "zod";
const schema = z.string();
// schema.parse(x) throws on failure
// schema.safeParse(x) returns { success, ... }parse Throws on Invalid Data
parse returns the validated value on success and throws a ZodError on failure, ideal when invalid data is truly exceptional.
import { z } from "zod";
const schema = z.number();
const ok = schema.parse(42); // 42
// schema.parse("nope"); // throws ZodErrorCatching Parse Errors
Wrap parse in try/catch to handle the thrown error, inspecting it for details about what failed.
import { z } from "zod";
const schema = z.number();
try {
schema.parse("nope");
} catch (err) {
if (err instanceof z.ZodError) {
console.log("Invalid:", err.issues.length);
}
}safeParse Returns a Result
safeParse never throws. It returns an object with success: true and data, or success: false and error.
import { z } from "zod";
const schema = z.number();
const result = schema.safeParse("nope");
// result is { success: false, error: ZodError }Narrowing the Result
The result is a discriminated union on success. Checking it narrows to either data or error.
import { z } from "zod";
const schema = z.object({ id: z.number() });
const result = schema.safeParse({ id: 1 });
if (result.success) {
console.log(result.data.id); // typed
} else {
console.log(result.error.issues);
}When to Use parse
Use parse when invalid input is a bug or should abort the operation, like reading required config at startup.
import { z } from "zod";
const configSchema = z.object({ port: z.number() });
const config = configSchema.parse({ port: 8080 });
// Fail fast if config is wrong.When to Use safeParse
Use safeParse when invalid input is expected and you want to handle it gracefully, like validating user form submissions.
import { z } from "zod";
const formSchema = z.object({ email: z.string() });
const r = formSchema.safeParse({ email: 123 });
if (!r.success) {
// Show a friendly validation message
}Reading ZodError Issues
A ZodError contains an issues array describing each problem: the path, a message, and the error code.
import { z } from "zod";
const schema = z.object({ age: z.number() });
const r = schema.safeParse({ age: "x" });
if (!r.success) {
for (const issue of r.error.issues) {
console.log(issue.path, issue.message);
}
}Both Return the Inferred Type
On success, both methods give you the validated value typed as z.infer<typeof schema>, so downstream code is fully typed.
import { z } from "zod";
const userSchema = z.object({ name: z.string() });
type User = z.infer<typeof userSchema>;
const u: User = userSchema.parse({ name: "Ada" });
console.log(u.name);Choosing the Right Method
Rule of thumb: parse for trusted or critical paths where failure should stop execution; safeParse for untrusted input you must handle without crashing.
import { z } from "zod";
const schema = z.string();
// Critical: schema.parse(value)
// User-facing: schema.safeParse(value)Combining Both Styles
A common pattern wraps safeParse in a helper that returns typed data or a formatted error, giving the ergonomics of both methods.
import { z } from "zod";
function validate<T extends z.ZodType>(schema: T, value: unknown) {
const r = schema.safeParse(value);
return r.success ? { ok: true, data: r.data } : { ok: false, error: r.error };
}
// Reusable, no throwing.Quick Check: parse vs safeParse
Test your understanding of parse versus safeParse.
Recap: parse vs safeParse
You learned that parse throws on invalid data while safeParse returns a success/error result, when to use each, and how to read ZodError issues.
import { z } from "zod";
const schema = z.object({ id: z.number() });
const r = schema.safeParse({ id: 1 });
if (r.success) console.log(r.data.id);Frequently asked questions
Is the “parse vs safeParse” lesson free?
Yes — the full text of “parse vs safeParse” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “parse vs safeParse”?
Handle validation success and failure gracefully. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “parse vs safeParse” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.