Readonly Modifier

▶ Open in Playground

Every schema builder supports .readonly(). This is a type-level-only modifier — it marks the inferred TypeScript type as immutable, but does not alter validation behaviour or freeze the validated value at runtime.

BuilderEffect on InferType<T>
object(…).readonly()Readonly<{ … }> — all top-level properties become readonly
array(…).readonly()ReadonlyArray<T> — no push, pop, etc. at the type level
date().readonly()Readonly<Date>
PrimitivesIdentity — string, number, boolean are already immutable
import { object, array, string, number, type InferType } from '@cleverbrush/schema';

// Readonly object — all properties become readonly at type level
const UserSchema = object({ name: string(), age: number() }).readonly();
type User = InferType<typeof UserSchema>;
// Readonly<{ name: string; age: number }>

// Readonly array — disables push, pop, etc.
const TagsSchema = array(string()).readonly();
type Tags = InferType<typeof TagsSchema>;
// ReadonlyArray<string>

// Chains naturally with .optional() and .default()
const Schema = object({ id: number() }).readonly().optional();
type T = InferType<typeof Schema>;
// Readonly<{ id: number }> | undefined

// isReadonly flag is exposed via .introspect()
const schema = object({ name: string() }).readonly();
console.log(schema.introspect().isReadonly); // true

Note: .readonly() is shallow — only top-level object properties or the array itself are marked readonly. For deeply nested immutability, apply .readonly() at each level.