diff --git a/src/ZodSchemaClass.ts b/src/ZodSchemaClass.ts index 697cf68..d968ecf 100644 --- a/src/ZodSchemaClass.ts +++ b/src/ZodSchemaClass.ts @@ -1,6 +1,7 @@ import { expression } from "@thilawyn/traitify-ts" import { AbstractClass } from "type-fest" import { z } from "zod" +import { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject" import { InstantiableZodSchemaObject } from "./traits/InstantiableZodSchemaObject" import { Extend, StaticMembers } from "./util" @@ -32,7 +33,10 @@ export function ZodSchemaClassOf< Object.assign(this, values) } }) - .expresses(InstantiableZodSchemaObject) + .expresses( + InstantiableZodSchemaObject, + ExtendableZodSchemaObject, + ) .build() return exp.extends as AbstractClass< diff --git a/src/tests.ts b/src/tests.ts index 682c96a..ded48e8 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -26,17 +26,17 @@ const inst = Test.create({ id: 1n, name: "" }) console.log(inst) -// class SubTest extends Test.extend({ -// schema: ({ schema }) => schema.extend({ -// prout: z.string() -// }), +class SubTest extends Test.extend({ + schema: ({ schema }) => schema.extend({ + prout: z.string() + }), -// defaultValues: defaultValues => defineDefaultValues({ -// ...defaultValues -// }), -// }) {} + defaultValues: defaultValues => ({ + ...defaultValues + }), +}) {} -// const subInst = await SubTest.createPromise({ name: "", prout: "" }) +const subInst = await SubTest.createPromise({ name: "", prout: "" }) // console.log(subInst) diff --git a/src/traits/ExtendableZodSchemaObject.ts b/src/traits/ExtendableZodSchemaObject.ts index ab1be36..dacb7bb 100644 --- a/src/traits/ExtendableZodSchemaObject.ts +++ b/src/traits/ExtendableZodSchemaObject.ts @@ -1,6 +1,8 @@ import { abstract, trait } from "@thilawyn/traitify-ts" +import { AbstractClass } from "type-fest" import { z } from "zod" import { ZodSchemaAbstractClass } from "../types/ZodSchemaClass" +import { Extend, StaticMembers } from "../util" export const ExtendableZodSchemaObject = trait( @@ -32,8 +34,26 @@ export const ExtendableZodSchemaObject = trait( defaultValues: (defaultValues: SuperDefaultValues) => DefaultValues }, + ): ( + AbstractClass< + Extend<[InstanceType, Values]>, + [values: Values] + > & + Extend<[ + StaticMembers, + { + readonly schema: z.ZodObject, + readonly defaultValues: DefaultValues, + }, + ]> ) { + const schema = props.schema({ schema: this.schema, shape: this.schema.shape }) + const defaultValues = props.defaultValues(this.defaultValues) + return class extends this { + static readonly schema = schema + static readonly defaultValues = defaultValues + } as any } }, ) diff --git a/src/traits/InstantiableZodSchemaObject.ts b/src/traits/InstantiableZodSchemaObject.ts index 2560cfc..fb70ca9 100644 --- a/src/traits/InstantiableZodSchemaObject.ts +++ b/src/traits/InstantiableZodSchemaObject.ts @@ -1,11 +1,31 @@ import { abstract, trait } from "@thilawyn/traitify-ts" import { Effect, pipe } from "effect" +import { HasRequiredKeys } from "type-fest" import { z } from "zod" -import { NewZodSchemaInstanceArgs, NewZodSchemaInstanceInput } from ".." import { ZodSchemaClass } from "../types/ZodSchemaClass" import { parseZodTypeEffect } from "../util" +type NewZodSchemaInstanceInput< + Values extends {}, + DefaultValues extends Partial, +> = { + [Key in Exclude]: Values[Key] +} & { + [Key in keyof DefaultValues]?: Key extends keyof Values + ? Values[Key] + : never +} + +type ParseParamsArgs = [] | [params: Partial] + +type NewZodSchemaInstanceArgs = ( + HasRequiredKeys extends true + ? [values: Input, ...args: ParseParamsArgs] + : [] | [values: Input, ...args: ParseParamsArgs] +) + + export const InstantiableZodSchemaObject = trait( abstract(),