Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Zod · Module

z.unknown

z.unknown() defines a schema that accepts any runtime value while inferring TypeScript’s safer unknown type. Use it when input shape is intentionally unrestricted but downstream code must narrow the value before using it.

How it works

z.unknown() creates a schema that accepts values of any type and infers the TypeScript type unknown. Unlike any, unknown requires consumers to narrow or validate the value before using type-specific operations. When used as an object property in Zod 4, the property remains required unless another schema explicitly makes it optional.

Syntax

z.unknown()

Returns

A Zod schema whose inferred output type is unknown and which accepts values of any runtime type.

Key points

  • The factory accepts any input while inferring the static TypeScript type unknown.
  • It is suitable at boundaries where the runtime value is intentionally unconstrained.
  • An object property using z.unknown() is required in the inferred object shape.
  • Its behavior is designed to correspond to TypeScript's special unknown type.

Common mistakes

  • Using z.unknown() as an object property does not make that property optional; the key is required in the inferred object type.
  • Code migrating from Zod 3 may infer required object keys instead of optional ones for z.unknown().

Example: Accept an unknown payload

import { z } from "zod";

const payloadSchema = z.object({
  payload: z.unknown(),
});

const result = payloadSchema.parse({ payload: { event: "created" } });
console.log(result.payload);

The schema accepts any runtime value for payload, while TypeScript keeps that value typed as unknown until the program narrows it.

When to use it

Accept data whose shape is not known at the schema boundary

External or extensible payloads

Preserve `unknown` until a later narrowing or schema check

Type-safe deferred validation

Represent required fields that may contain any runtime value

Generic object fields

Interview questions

QWhat is the difference between z.unknown() and z.any()?

z.unknown() accepts values of any runtime type, but its inferred TypeScript type is unknown. This is safer than any because callers must narrow the value before treating it as a specific type.

Follow-up: How would you make an unknown value optional in an object? Wrap the schema with .optional(), such as z.unknown().optional().

QDoes z.unknown() make an object property optional?

A property defined as z.unknown() is required in the inferred object type in current Zod. The schema accepts any value for that property, including values whose runtime type is not otherwise constrained.

Follow-up: What change matters when migrating from Zod 3? In Zod 4, z.unknown() no longer causes the object key to be inferred as optional.

QWhen is z.unknown() useful?

Use z.unknown() when the value is intentionally unconstrained at the schema boundary but should remain type-safe in TypeScript. After parsing, narrow it with runtime checks or pass it to another Zod schema.

Follow-up: How can an unknown value be constrained later? Compose a more specific schema, such as z.object({...}), and parse or validate the value against that schema.

  • z.any()
  • z.object()
  • z.optional()
  • z.record()

Source: Defining schemas. Checked 2026-10-15.