One or more ExtensionDescriptors created by defineExtension.
An object with factory functions for all builder types
(string, number, boolean, date, object, array, union,
func, any), each returning augmented builders.
const s = withExtensions(emailExt, rangeExt);
// string() now has .email()
const emailSchema = s.string().email().minLength(5);
// number() now has .range()
const rangeSchema = s.number().range(0, 100);
// builders without targeted extensions work as normal
const dateSchema = s.date();
const s = withExtensions(emailExt, slugExt, trimmedExt);
const schema = s.string().email().slug().trimmed();
const s = withExtensions(emailExt, portExt);
const ServerConfig = s.object({
host: s.string().email(),
port: s.number().port()
});
Creates a set of schema factory functions with the provided extensions applied.
Each factory function (
string(),number(),date(), …) returned bywithExtensionsproduces builder instances whose prototypes include the extension methods. All built-in builder methods remain available and fully chainable alongside the new ones.Stacking multiple extensions
Pass any number of ExtensionDescriptors — their methods are merged per builder type. If two extensions define the same method name on the same builder type, a runtime error is thrown to prevent silent conflicts.
Type safety
The return type is fully inferred: TypeScript knows exactly which extension methods are available on each builder factory. Extension methods return the full extended builder type, so chaining like
s.string().email().slug().minLength(3)is fully typed.Builder types without extensions
Builders that have no methods from any of the provided extensions use the standard (unextended) factory, so there is zero overhead.