import { AbstractClass, Class as ConcreteClass } from "type-fest" import { z } from "zod" import { StaticMembers } from "./util" export function makeSchemableClassFrom< C extends AbstractClass, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends {}, DefaultValues extends Partial, >( extend: C, schema: z.ZodObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values >, defaultValues: DefaultValues, ) { type Class = ( C extends ConcreteClass ? ConcreteClass : AbstractClass ) return class extends (extend as unknown as ConcreteClass) { static readonly schema = schema readonly schema = schema static readonly defaultValues = defaultValues readonly defaultValues = defaultValues constructor(values: Values) { super() Object.assign(this, values) } } as unknown as ( Class< Omit, "schema" | "defaultValues"> & { readonly schema: typeof schema, readonly defaultValues: typeof defaultValues, } & Values, Parameters<(values: Values) => void> > & Omit, "schema" | "defaultValues"> & { readonly schema: typeof schema, readonly defaultValues: typeof defaultValues, } ) } export function makeSchemableClass< SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends {}, DefaultValues extends Partial, >( schema: z.ZodObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values >, defaultValues: DefaultValues, ) { return makeSchemableClassFrom(Object, schema, defaultValues) }