A (generic) function that accepts schema arguments and
returns a concrete schema. TypeScript infers the result type from this
function's generic signature when .apply() is called.
A new GenericSchemaBuilder with isRequired set to true.
import { generic, object, array, number, string, any, InferType } from '@cleverbrush/schema';
const PaginatedList = generic(
<T extends SchemaBuilder<any, any, any, any, any>>(itemSchema: T) =>
object({ items: array(itemSchema), total: number(), page: number() })
);
const UserList = PaginatedList.apply(object({ name: string() }));
type UserListType = InferType<typeof UserList>;
// → { items: { name: string }[]; total: number; page: number }
UserList.validate({ items: [{ name: 'Alice' }], total: 1, page: 1 }); // valid
const Result = generic(
<T extends SchemaBuilder<any, any, any, any, any>,
E extends SchemaBuilder<any, any, any, any, any>>(
valueSchema: T,
errorSchema: E
) =>
union(
object({ ok: boolean().equalsTo(true), value: valueSchema }),
object({ ok: boolean().equalsTo(false), error: errorSchema })
)
);
const StringResult = Result.apply(string(), number());
const AnyList = generic(
[any()], // default args — positional, one per template parameter
<T extends SchemaBuilder<any, any, any, any, any>>(itemSchema: T) =>
object({ items: array(itemSchema), total: number() })
);
// Validate directly — uses the default any() schema:
AnyList.validate({ items: [1, 'two'], total: 2 }); // valid
// Or apply concrete schemas first:
AnyList.apply(string()).validate({ items: ['x'], total: 1 }); // valid
Creates a generic schema template — a reusable, parameterized schema factory whose TypeScript type is inferred from the template function's generic signature.
Call .apply() on the returned builder
to instantiate the template with concrete schema arguments and receive a
fully typed concrete schema.
There are two overloads:
generic(templateFn) — Provide only the template function. The
template must be called via .apply() before validation.generic(defaults, templateFn) — Provide positional default arguments
followed by the template function. The template can be validated directly
using those defaults (without calling .apply() first).A (generic) function that accepts schema arguments and
returns a concrete schema. TypeScript infers the result type from this
function's generic signature when .apply() is called.
A new GenericSchemaBuilder with isRequired set to true.
import { generic, object, array, number, string, any, InferType } from '@cleverbrush/schema';
const PaginatedList = generic(
<T extends SchemaBuilder<any, any, any, any, any>>(itemSchema: T) =>
object({ items: array(itemSchema), total: number(), page: number() })
);
const UserList = PaginatedList.apply(object({ name: string() }));
type UserListType = InferType<typeof UserList>;
// → { items: { name: string }[]; total: number; page: number }
UserList.validate({ items: [{ name: 'Alice' }], total: 1, page: 1 }); // valid
const Result = generic(
<T extends SchemaBuilder<any, any, any, any, any>,
E extends SchemaBuilder<any, any, any, any, any>>(
valueSchema: T,
errorSchema: E
) =>
union(
object({ ok: boolean().equalsTo(true), value: valueSchema }),
object({ ok: boolean().equalsTo(false), error: errorSchema })
)
);
const StringResult = Result.apply(string(), number());
const AnyList = generic(
[any()], // default args — positional, one per template parameter
<T extends SchemaBuilder<any, any, any, any, any>>(itemSchema: T) =>
object({ items: array(itemSchema), total: number() })
);
// Validate directly — uses the default any() schema:
AnyList.validate({ items: [1, 'two'], total: 2 }); // valid
// Or apply concrete schemas first:
AnyList.apply(string()).validate({ items: ['x'], total: 1 }); // valid
Creates a generic schema template — a reusable, parameterized schema factory whose TypeScript type is inferred from the template function's generic signature.
Call
.apply()on the returned builder to instantiate the template with concrete schema arguments and receive a fully typed concrete schema.There are two overloads:
generic(templateFn)— Provide only the template function. The template must be called via.apply()before validation.generic(defaults, templateFn)— Provide positional default arguments followed by the template function. The template can be validated directly using those defaults (without calling.apply()first).