From e7c65c0a07b193b87beffe9bdcf4182cc44aa6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 25 Feb 2024 04:32:09 +0100 Subject: [PATCH] ZodSchemaClassExtender --- src/builders/ZodSchemaClassBuilder.ts | 18 ++++---- src/builders/ZodSchemaClassExtender.ts | 59 ++++++++++++++++++++++++++ src/util/extend.ts | 8 ++-- 3 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 src/builders/ZodSchemaClassExtender.ts diff --git a/src/builders/ZodSchemaClassBuilder.ts b/src/builders/ZodSchemaClassBuilder.ts index 75b85f1..fe12b66 100644 --- a/src/builders/ZodSchemaClassBuilder.ts +++ b/src/builders/ZodSchemaClassBuilder.ts @@ -18,7 +18,7 @@ extends TraitExpressionBuilder { declare ["constructor"]: typeof ZodSchemaClassBuilder schema< - Superclass extends AbstractClass & { schema?: never, defaultValues?: never }, + Super extends AbstractClass & { schema?: never, defaultValues?: never }, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, @@ -27,7 +27,7 @@ extends TraitExpressionBuilder { Values extends object, DefaultValues extends Partial, >( - this: ZodSchemaClassBuilder, + this: ZodSchemaClassBuilder, { schema, defaultValues }: { schema: z.ZodObject @@ -47,10 +47,10 @@ extends TraitExpressionBuilder { return new this.constructor( Schemas as unknown as ( AbstractClass< - InstanceType & Values, + InstanceType & Values, ConstructorParameters > & - StaticMembers & + StaticMembers & StaticMembers ), @@ -63,7 +63,7 @@ extends TraitExpressionBuilder { } jsonifiable< - Superclass extends ZodSchemaAbstractClass + Super extends ZodSchemaAbstractClass & { jsonifySchema?: never, dejsonifySchema?: never }, Instance extends Values, @@ -85,7 +85,7 @@ extends TraitExpressionBuilder { JsonifiedValues extends JsonifiableObject, >( this: ZodSchemaClassBuilder< - Superclass | ZodSchemaAbstractClass, + Super | ZodSchemaAbstractClass, Traits >, @@ -112,12 +112,12 @@ extends TraitExpressionBuilder { return new this.constructor( JsonifiableSchemas as unknown as ( AbstractClass< - InstanceType & JsonifiableSchemas, + Instance & JsonifiableSchemas, - // TODO: for some reason, ConstructorParameters does not work here. Maybe try to find a fix? + // TODO: for some reason, ConstructorParameters does not work here. Maybe try to find a fix? ConstructorParameters> > & - StaticMembers & + StaticMembers & StaticMembers ), diff --git a/src/builders/ZodSchemaClassExtender.ts b/src/builders/ZodSchemaClassExtender.ts new file mode 100644 index 0000000..d365476 --- /dev/null +++ b/src/builders/ZodSchemaClassExtender.ts @@ -0,0 +1,59 @@ +import { AbstractClass } from "type-fest" +import { z } from "zod" +import { ZodSchemaAbstractClass } from "../shapes/ZodSchemaClass" +import { Extend, StaticMembers } from "../util" + + +export class ZodSchemaClassExtender> { + declare ["constructor"]: typeof ZodSchemaClassExtender + + constructor(readonly superclass: Superclass) {} + + + schema< + Super extends ZodSchemaAbstractClass, + SuperInstance extends SuperValues, + + SuperSchemaT extends z.ZodRawShape, + SuperSchemaUnknownKeys extends z.UnknownKeysParam, + SuperSchemaCatchall extends z.ZodTypeAny, + + SuperValues extends object, + SuperDefaultValues extends Partial, + + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends SuperValues, + DefaultValues extends Partial, + >( + this: ZodSchemaClassExtender< + Super | ZodSchemaAbstractClass + >, + + props: { + schema: (schema: Super["schema"]) => z.ZodObject + defaultValues: (defaultValues: SuperDefaultValues) => DefaultValues + }, + ) { + const schema = props.schema(this.superclass.schema) + const defaultValues = props.defaultValues(this.superclass.defaultValues) + + class Schemas extends (this.superclass as AbstractClass) { + static readonly schema = schema + static readonly defaultValues = defaultValues + } + + return new this.constructor( + this.superclass as unknown as AbstractClass< + Extend<[SuperInstance, Schemas]>, + [values: Values] + > & + Extend<[ + StaticMembers, + StaticMembers, + ]> + ) + } +} diff --git a/src/util/extend.ts b/src/util/extend.ts index baa104d..5cab210 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -6,18 +6,18 @@ export type CommonKeys = Extract export type Extend = ( - T extends [ + T extends readonly [ infer Super, infer Self, - ...infer Rest extends object[], + ...infer Rest extends readonly object[], ] ? Pick> extends Pick> - ? Extend<[ + ? Extend> & Self, ...Rest, ]> : never - : T extends [infer Self] + : T extends readonly [infer Self] ? Self : {} )