Skip to content

There's no ergonomic way to rename object properties or do .partial() etc on object transformation pipelines #2470

@jedwards1211

Description

@jedwards1211

Consider the case where you want to build an API response with camelCase properties in JS, and then send it over the wire with snake_case properties:

const Post =
  z.object({
    id: z.string(),
    body: z.string(),
    userId: z.string(),
  })
  .transform(
    ({ userId, ...rest }) => ({ ...rest, user_id: userId })
  )
  .pipe(z.object({
    id: z.string(),
    body: z.string(),
    user_id: z.string(),
  }))

You might want to do .partial() if you have another API that allows the user to pick a selection of fields from a Post:

const PostSelection = Post.partial() // plz?

One could create the following helper function for this. But this all feels very cumbersome. Maybe in an alternate universe, Zod has a more ergonomic way to do all of this?

function pipelinePartial(schema) {
  if (schema instanceof z.ZodObject) {
    return schema.partial()
  }
  if (schema instanceof z.ZodPipeline) {
    return z.pipeline(pipelinePartial(schema._def.in), pipelinePartial(schema._def.out))
  }
  if (schema instanceof z.ZodEffects) {
    return z.effects(pipelinePartial(schema._def.schema), schema._def.effect)
  }
  throw new Error(`unsupported schema type: ${schema.constructor.name}`)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions