ZodSchemaClass
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Julien Valverdé
2024-01-21 20:15:25 +01:00
parent fc95a5d53a
commit 6873fae86b
4 changed files with 212 additions and 0 deletions

176
src/ZodSchemaClass.ts Normal file
View File

@@ -0,0 +1,176 @@
import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest"
import { z } from "zod"
import { DefinedDefaultValuesTag } from "."
import { StaticMembers } from "./util"
export type TZodSchemaClass<
Schema extends z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends {},
DefaultValues extends Partial<Values>,
> = (
AbstractClass<
{
readonly schema: Schema
readonly defaultValues: DefaultValues
} & Values,
[values: Values]
> & {
readonly schema: Schema
readonly defaultValues: DefaultValues
newPromise<Self extends ConcreteClass<any>>(this: Self): Promise<InstanceType<Self>>
extend<
Parent
>(
this: Parent
): Parent
}
)
type ExtendableClass = AbstractClass<{
schema?: never
defaultValues?: never
}, []> & {
schema?: never
defaultValues?: never
}
function makeClass<
Self,
Parent extends ExtendableClass,
Schema extends z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends {},
DefaultValues extends Partial<Values>,
>(
{ of, schema, defaultValues }: {
self: Self,
of: Parent,
schema: Schema | z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
defaultValues: Opaque<DefaultValues, DefinedDefaultValuesTag>
},
) {
type Class<T, Arguments extends unknown[]> = (
Parent extends ConcreteClass<any>
? ConcreteClass<T, Arguments>
: AbstractClass<T, Arguments>
)
type ZodClass = TZodSchemaClass<
Schema,
SchemaT,
SchemaUnknownKeys,
SchemaCatchall,
Values,
DefaultValues
>
return class extends (of as unknown as ConcreteClass<any, []>) {
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<
InstanceType<Parent> &
InstanceType<ZodClass>,
ConstructorParameters<ZodClass>
> &
StaticMembers<Parent> &
StaticMembers<ZodClass>
)
}
export function ZodSchemaClassOf<Self>() {
return <
Parent extends ExtendableClass,
Schema extends z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends {},
DefaultValues extends Partial<Values>,
>(
of: Parent,
props: Omit<
Parameters<
typeof makeClass<
Self,
Parent,
Schema,
SchemaT,
SchemaUnknownKeys,
SchemaCatchall,
Values,
DefaultValues
>
>[0], "self" | "of"
>,
) => makeClass({
...props,
self: {} as Self,
of,
})
}
const DefaultParent = Object
export function ZodSchemaClass<Self>() {
return <
Schema extends z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends {},
DefaultValues extends Partial<Values>,
>(
props: Omit<
Parameters<
typeof makeClass<
Self,
typeof DefaultParent,
Schema,
SchemaT,
SchemaUnknownKeys,
SchemaCatchall,
Values,
DefaultValues
>
>[0], "self" | "of"
>,
) => makeClass({
...props,
self: {} as Self,
of: DefaultParent,
})
}