Objects
Prefer callable p({...}) to create an object schema. The explicit
p.object({...}) factory is equivalent and remains available for completeness.
Nested schema shorthand is normalized recursively.
const User = p({
name: p.string,
settings: {
alerts: p.boolean.default(true),
},
});ObjectType exposes properties, its inferred input, optional(),
extend(), shape<T>(), closed() and min().
Unknown properties
Objects discard undeclared input properties by default:
p({ name: p.string }).parse({ name: "Ada", admin: true });
// { name: "Ada" }
Closed objects
Use closed() to reject them instead:
const User = p({ name: p.string }).closed();
User.parse({ name: "Ada", admin: true });
// unknown_property at /adminThe issue path is an escaped JSON Pointer. Closing is local: nested object
schemas remain open unless they also call closed(). This policy is unrelated
to p.strict, which controls coercion.
Minimum supplied properties
Object min(n) requires at least n supplied, declared properties to parse
successfully. A property counts only when it is an own enumerable input
property and its raw value is not undefined. Unknown fields and values created
only by defaults do not count.
const Patch = p({
name: p.string.optional(),
enabled: p.boolean.default(true),
}).min(1);
Patch.parse({}); // too_small
Patch.parse({ name: "Ada" }); // validThe bound must be a finite, nonnegative integer.
Partial updates
p.partial(shape) makes every declared property optional without changing its
validator. It accepts a property map or an ObjectType.
const User = {
name: p.string,
email: p.string.email(),
};
const UpdateUser = p.partial(User).closed().min(1);This pattern rejects empty updates and misspelled fields. PartialType also
supports default(), derive(), closed() and min().
Extend, shape and omit
extend() adds nonconflicting properties. Policies belong to the receiver:
const Base = p({ id: p.u32 }).closed();
const User = Base.extend({ name: p.string });The result remains closed. If the extension argument is another object schema,
only its properties are imported, not its closed or min policies.
shape<T>() aliases the inferred output type while preserving runtime parsing;
it does not add runtime validation. p.omit(schema, ...keys) creates an
OmitType without the named properties:
const PublicUser = p.omit(User, "id");
Async objects
p.async(shape) creates an AsyncType for object parsing followed by async
derivation:
const Account = p.async({ id: p.string })
.derive(async ({ id }) => await loadAccount(id));
const account = await Account.parse({ id: "ada" });Async schemas expose parse(), derive(), infer, input, schema and
properties. They are useful as Primate route body and path schemas, but are
validation-only and not direct Store fields.
See Errors for object issue paths and Input validation for route integration.