docs
guides
reference
Literal value validation for exact value matching with static types and primitive literal schemas.
Creates a schema that validates an exact literal value with strong type inference.
/**
* Create a literal value validator
* @param value - The exact primitive value to match
* @returns Literal schema that only accepts the specified value
*/
function literal<T extends Primitive>(value: T): ZodLiteral<T>;
type Primitive = string | number | boolean | null | undefined | symbol | bigint;Usage Examples:
import * as z from 'zod';
// String literal
const Hello = z.literal('hello');
Hello.parse('hello'); // => "hello"
// Hello.parse('world'); // throws error
// Number literal
const FortyTwo = z.literal(42);
FortyTwo.parse(42); // => 42
// FortyTwo.parse(43); // throws error
// Boolean literal
const TrueOnly = z.literal(true);
TrueOnly.parse(true); // => true
// TrueOnly.parse(false); // throws error
// Null literal
const NullOnly = z.literal(null);
NullOnly.parse(null); // => null
// BigInt literal
const BigIntLiteral = z.literal(9007199254740991n);
BigIntLiteral.parse(9007199254740991n); // => 9007199254740991n
// Use in type inference
type HelloType = z.infer<typeof Hello>; // "hello"
type FortyTwoType = z.infer<typeof FortyTwo>; // 42Literal schemas are commonly combined with unions to create enumeration-like types:
import * as z from 'zod';
// Status enum using literals
const Status = z.union([
z.literal('pending'),
z.literal('active'),
z.literal('completed'),
]);
type Status = z.infer<typeof Status>; // "pending" | "active" | "completed"
Status.parse('active'); // => "active"
// Better approach using z.enum() for string literals
const BetterStatus = z.enum(['pending', 'active', 'completed']);
// Mixed literal types
const MixedLiteral = z.union([
z.literal('auto'),
z.literal(0),
z.literal(false),
]);
type MixedLiteral = z.infer<typeof MixedLiteral>; // "auto" | 0 | falseLiteral schemas are essential for discriminated unions:
import * as z from 'zod';
// Discriminated union using literal discriminators
const Shape = z.discriminatedUnion('kind', [
z.object({
kind: z.literal('circle'),
radius: z.number(),
}),
z.object({
kind: z.literal('rectangle'),
width: z.number(),
height: z.number(),
}),
]);
type Shape = z.infer<typeof Shape>;
// { kind: "circle"; radius: number } | { kind: "rectangle"; width: number; height: number }
Shape.parse({ kind: 'circle', radius: 5 });
Shape.parse({ kind: 'rectangle', width: 10, height: 20 });Creates a schema that only accepts null values.
/**
* Create a null literal validator
* @returns Schema that only accepts null
*/
function null_(): ZodNull;Usage Examples:
import * as z from 'zod';
const NullSchema = z.null();
NullSchema.parse(null); // => null
// NullSchema.parse(undefined); // throws error
// Often used with nullable modifier
const NullableString = z.string().nullable();
type NullableString = z.infer<typeof NullableString>; // string | nullCreates a schema that only accepts undefined values.
/**
* Create an undefined literal validator
* @returns Schema that only accepts undefined
*/
function undefined_(): ZodUndefined;Usage Examples:
import * as z from 'zod';
const UndefinedSchema = z.undefined();
UndefinedSchema.parse(undefined); // => undefined
// UndefinedSchema.parse(null); // throws error
// Often used with optional modifier
const OptionalString = z.string().optional();
type OptionalString = z.infer<typeof OptionalString>; // string | undefinedCreates a schema that accepts undefined but with void type semantics.
/**
* Create a void literal validator (accepts undefined)
* @returns Schema that accepts undefined with void type
*/
function void_(): ZodVoid;Usage Examples:
import * as z from 'zod';
const VoidSchema = z.void();
VoidSchema.parse(undefined); // => undefined (typed as void)
// Useful for function return types
const VoidFunction = z._function({
args: z.tuple([z.string()]),
returns: z.void(),
});Symbols can be used as literals but require specific symbol instances:
import * as z from 'zod';
const mySymbol = Symbol('unique');
const SymbolLiteral = z.literal(mySymbol);
SymbolLiteral.parse(mySymbol); // => Symbol(unique)
// SymbolLiteral.parse(Symbol('unique')); // throws error (different symbol instance)Common patterns for working with literal types:
import * as z from 'zod';
// Action type pattern
const Action = z.object({
type: z.literal('UPDATE_USER'),
payload: z.object({
userId: z.string(),
name: z.string(),
}),
});
// API response status pattern
const SuccessResponse = z.object({
success: z.literal(true),
data: z.any(),
});
const ErrorResponse = z.object({
success: z.literal(false),
error: z.string(),
});
const APIResponse = z.union([SuccessResponse, ErrorResponse]);
// Type guard using literal
function isSuccess(response: z.infer<typeof APIResponse>): response is z.infer<typeof SuccessResponse> {
return response.success === true;
}All literal schemas support common schema methods:
interface ZodLiteral<T extends Primitive> {
// Parsing
parse(data: unknown): T;
safeParse(data: unknown): SafeParseReturnType<unknown, T>;
// Modifiers
optional(): ZodOptional<ZodLiteral<T>>;
nullable(): ZodNullable<ZodLiteral<T>>;
default(value: T): ZodDefault<ZodLiteral<T>>;
// Refinement and transformation
refine(
check: (data: T) => boolean | Promise<boolean>,
params?: RefineParams
): ZodEffects<ZodLiteral<T>>;
transform<NewOut>(
transform: (data: T) => NewOut | Promise<NewOut>
): ZodEffects<ZodLiteral<T>, NewOut>;
// Metadata
describe(description: string): ZodLiteral<T>;
meta(metadata: any): ZodLiteral<T>;
}type Primitive = string | number | boolean | null | undefined | symbol | bigint;
class ZodLiteral<T extends Primitive> {
readonly _type: 'ZodLiteral';
readonly value: T;
}
class ZodNull {
readonly _type: 'ZodNull';
}
class ZodUndefined {
readonly _type: 'ZodUndefined';
}
class ZodVoid {
readonly _type: 'ZodVoid';
}
interface RefineParams {
message?: string;
path?: (string | number)[];
}
type SafeParseReturnType<Input, Output> =
| { success: true; data: Output }
| { success: false; error: ZodError<Input> };
class ZodError<T = any> extends Error {
issues: ZodIssue[];
}