Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ezmiks's avatar

ezmiks started a new conversation+100 XP

3mos ago

Zod object to plain object (with default values)

Is there a way for zodobject to be converted to a plain object?

Like, I have the following schema:

const schema = z.object({
	name: z.string().default(someResource?.name ?? null),
	email: z.email().optional().default(someResource?.email ?? null),
	address: z.string().optional().default(someResource?.address ?? null),
})

and I have tried: schema.parse({}) and it seems like it gives me a plain object, but without the default values of someObject (for this example's sake, let's just say someObject is not undefined or null).

I'm asking this question, because it's very inconvenient if I create the same object for the initial form data values like:

const formData = {
    name: someResource?.name ?? null,
 	email: someResource?.email ?? null,
	address: someResource?.address ?? null)
}

// and then define again the same fields:
const schema = z.object({
	name: z.string().default(someResource?.name ?? null),
	email: z.email().optional().default(someResource?.email ?? null),
	address: z.string().optional().default(someResource?.address ?? null),
})

because what if I have over 10 fields, it would be very tiresome to re-define the same fields for formData and for the schema

ezmiks's avatar

ezmiks started a new conversation+100 XP

5mos ago

How to enforce immediate type safety on a ValueObject-casted model property?

Hello,

I have a model DepositMethod, and one of its property is called cost_settings

I casted it like this:

'cost_settings' => AsCollection::of(CostSettingData::Class)

but as far as I know, this casting only mutates the data when accessed. Is there a way to also enforce error if any value formats other than CostSettingData is provided?

Because when I push data like $depositMethod->cost_settings->push(['random' => 'value']), this still works, and I don't want that. One way of course is to validate the request, but I still prefer if it throws an error immediately. Because I want to avoid any format being inserted wrongfully by other devs for some reason.