Files
zod-schema-class/src/extendSchemableClass.ts
Julien Valverdé bfa359449e
All checks were successful
continuous-integration/drone/push Build is passing
dejsonifySchemable
2024-01-16 14:44:54 +01:00

96 lines
2.8 KiB
TypeScript

import { AbstractClass, Class as ConcreteClass } from "type-fest"
import { z } from "zod"
import { SchemableClass } from "."
import { StaticMembers } from "./util"
export function extendSchemableClass<
C extends SchemableClass<
ExtendSchemaT,
ExtendSchemaUnknownKeys,
ExtendSchemaCatchall,
ExtendSchemaValues,
ExtendDefaultValues
>,
ExtendSchemaT extends z.ZodRawShape,
ExtendSchemaUnknownKeys extends z.UnknownKeysParam,
ExtendSchemaCatchall extends z.ZodTypeAny,
ExtendSchemaValues extends {},
ExtendDefaultValues extends Partial<ExtendSchemaValues>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
SchemaValues extends ExtendSchemaValues,
DefaultValues extends Partial<SchemaValues>,
>(
extend: C | SchemableClass<
ExtendSchemaT,
ExtendSchemaUnknownKeys,
ExtendSchemaCatchall,
ExtendSchemaValues,
ExtendDefaultValues
>,
props: {
schema: (props: {
schema: z.ZodObject<
ExtendSchemaT,
ExtendSchemaUnknownKeys,
ExtendSchemaCatchall,
ExtendSchemaValues,
ExtendSchemaValues
>
shape: ExtendSchemaT
}) => z.ZodObject<
SchemaT,
SchemaUnknownKeys,
SchemaCatchall,
SchemaValues,
SchemaValues
>
defaultValues: (defaultValues: ExtendDefaultValues) => DefaultValues
},
) {
type Class<T, Arguments extends unknown[]> = (
C extends ConcreteClass<any>
? ConcreteClass<T, Arguments>
: AbstractClass<T, Arguments>
)
const schema = props.schema({
schema: extend.schema,
shape: extend.schema.shape,
})
const defaultValues = props.defaultValues(extend.defaultValues)
return class extends extend {
static readonly schema = schema
readonly schema = schema
static readonly defaultValues = defaultValues
readonly defaultValues = defaultValues
} as unknown as (
Class<
Omit<InstanceType<C>, "schema" | "defaultValues" | keyof ExtendSchemaValues> &
{
readonly schema: typeof schema,
readonly defaultValues: typeof defaultValues,
} &
SchemaValues,
Parameters<(values: SchemaValues) => void>
> &
Omit<StaticMembers<C>, "schema" | "defaultValues"> &
{
readonly schema: typeof schema,
readonly defaultValues: typeof defaultValues,
}
)
}