colinhacks / zod

TypeScript-first schema validation with static type inference
https://zod.dev
MIT License
34.21k stars 1.2k forks source link

Intersection between `z.object` and `z.record` incorrectly merges validators #2573

Open lars-berger opened 1 year ago

lars-berger commented 1 year ago

When intersecting a z.object and a z.record, zod applies validators for the keys and values of the record to the rest of the object.

const ConfigSchema = z
  .object({
    name: z.object({
      first: z.string(),
    }),
  })
  .and(
    z.record(
      z.enum(['a', 'b']),
      z.object({
        sub: z.string(),
      })
    )
  );

const validInput: z.infer<typeof ConfigSchema> = { // typescript type is correct and doesn't complain here 👍
  name: {
    first: '',
  },
  a: {
    sub: '',
  },
};

ConfigSchema.parse(validInput);
// ^ this throws 2 errors because:
// 1. 'name' doesn't match ['a', 'b']
// 2. 'name.sub' is required (even though this will never exist)
image

Reproduction URL: stackblitz.com

Expected behavior: validators for record keys and values should only apply to the record.

The same problem occurs with intersections of records that have native enum keys and template literal keys (eg. [key: dynamic/${string}]).

GauBen commented 11 months ago

Related to #2195

yovanoc commented 10 months ago

is there any alternative?