Last Updated: 3/12/2026
Literals
Literal schemas represent a literal type , like "hello world" or 5.
Basic Literals
import * as z from "zod";
const tuna = z.literal("tuna");
const twelve = z.literal(12);
const twobig = z.literal(2n); // BigInt literal
const tru = z.literal(true);
tuna.parse("tuna"); // ✅ "tuna"
tuna.parse("salmon"); // ❌ throwsSpecial Literals
To represent the JavaScript literals null and undefined:
z.null();
z.undefined();
z.void(); // equivalent to z.undefined()Multiple Literal Values
To allow multiple literal values, you can pass an array:
const colors = z.literal(["red", "green", "blue"]);
colors.parse("green"); // ✅
colors.parse("yellow"); // ❌ throwsExtracting Values
To extract the set of allowed values from a literal schema:
colors.values; // => Set<"red" | "green" | "blue">Literals vs Enums
While literals and enums might seem similar, they serve different purposes:
Literals
- Represent a single specific value
- Useful for exact value matching
- Often used in discriminated unions
const status = z.literal("success");
// Only accepts exactly "success"Enums
- Represent a set of possible values
- Provide utility methods (
.enum,.exclude(),.extract()) - Better for multiple options
const status = z.enum(["success", "error", "pending"]);
// Accepts any of the three valuesCommon Use Cases
Discriminated Unions
Literals are commonly used as discriminators in union types:
const Result = z.discriminatedUnion("status", [
z.object({
status: z.literal("success"),
data: z.string()
}),
z.object({
status: z.literal("error"),
error: z.string()
}),
]);Boolean Flags
const enabled = z.literal(true);
const disabled = z.literal(false);Magic Numbers
const HTTP_OK = z.literal(200);
const HTTP_NOT_FOUND = z.literal(404);Versioning
const ApiV1 = z.object({
version: z.literal(1),
// ... v1 fields
});
const ApiV2 = z.object({
version: z.literal(2),
// ... v2 fields
});
const ApiRequest = z.union([ApiV1, ApiV2]);Type Inference
const schema = z.literal("hello");
type Schema = z.infer<typeof schema>; // "hello" (not string)
const numSchema = z.literal(42);
type NumSchema = z.infer<typeof numSchema>; // 42 (not number)Best Practices
- Use literals for discriminators in discriminated unions
- Use enums for multiple options instead of unions of literals
- Prefer literals over magic values for better type safety
- Combine with unions to create flexible yet type-safe schemas