import { AbstractClass, Class } from "type-fest" import { z } from "zod" import { StaticMembers } from "./util" type SchemableClass< SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, SchemaValues extends {}, > = ( AbstractClass< { readonly schema: z.ZodObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaValues, SchemaValues > } & SchemaValues, any[] > & { readonly schema: z.ZodObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaValues, SchemaValues > } ) export function extendWithZodSchema< C extends SchemableClass< ExtendSchemaT, ExtendSchemaUnknownKeys, ExtendSchemaCatchall, ExtendSchemaValues >, ExtendSchemaT extends z.ZodRawShape, ExtendSchemaUnknownKeys extends z.UnknownKeysParam, ExtendSchemaCatchall extends z.ZodTypeAny, ExtendSchemaValues extends {}, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, SchemaValues extends ExtendSchemaValues, >( extend: C | SchemableClass< ExtendSchemaT, ExtendSchemaUnknownKeys, ExtendSchemaCatchall, ExtendSchemaValues >, schema: z.ZodObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaValues, SchemaValues >, ) { return class extends extend { static readonly schema = schema readonly schema = schema } as unknown as ( Class< Omit & { readonly schema: typeof schema } & SchemaValues, ConstructorParameters > & Omit, "schema"> & { readonly schema: typeof schema } ) } const Test1Schema = z.object({ prout: z.string() }) class Test1 { static readonly schema = Test1Schema readonly schema = Test1Schema prout: string = "heugneu" } const Test2Schema = Test1.schema.extend({ prout: z.literal("ruquier"), ruquier: z.number() }) const Test2 = extendWithZodSchema(Test1, Test2Schema) Test2.schema new Test2().prout