‘Z Unknown’ — commonly known as Zod unknown—is Zod’s strictest “accept anything without trusting it” type. It allows any input but keeps TypeScript from assuming what the value actually is.
Unlike z.any(), unknown forces you to refine, narrow, or check before using the value.
Code Example:
z.unknown()
Why Developers Use Zod Unknown
Developers reach for z.unknown() when dealing with messy, unpredictable, or untyped data sources. It becomes extremely useful in situations like:
- Unpredictable API payloads where the backend response shape may vary.
- User-generated metadata that you cannot predefine.
- Third-party integrations where structure isn’t guaranteed.
- Large JSON blobs that may contain mixed data types.
- Plugin or extension systems where fields evolve over time.
- Handling
anyin TypeScript the “safe way”. - Temporarily storing data before narrowing it.
It basically holds data in a “safe quarantine zone” until you decide what its real type should be.
Zod Unknown Type vs Zod Any — Key Differences
| Feature | z.any() | z.unknown() |
|---|---|---|
| Safety | Low | High |
| TypeScript trust level | Fully trusted | Must be narrowed |
| Best used for | Legacy/loose schemas | Dynamic but safe validation |
Short rule:
Use z.any() when you genuinely don’t care about structure.
Use z.unknown() when you don’t know the structure yet, but want to enforce safety.
Zod Unknown Object — Accepting Unknown Structures
If you want to accept an entire unknown structure:
const payloadSchema = z.unknown();
This simply says:
“I’ll take whatever you give me, but I’m not assuming anything.”
If you expect the value might be an object, you can refine it:
const objSchema = z.unknown().refine(v => typeof v === "object");
Great for handling unpredictable API responses or plugin-defined data structures.
Inferring Types From Unknown
When you infer a type from z.unknown(), the resulting TS type is literally:
type Meta = z.infer<typeof schema>; // unknown
This prevents TypeScript from letting you access properties or treat the value as if it’s already validated — which is exactly the point.
Summary
z.unknown() is Zod’s strict, type-safe way to accept any value without assuming its structure. It keeps unpredictable data—like API payloads, dynamic JSON, and user-generated fields—fully flexible while ensuring TypeScript never trusts the value until you refine or validate it.
This gives you freedom at runtime and safety at compile time, making z.unknown() the ideal choice when working with data you can’t define upfront.