zod icon indicating copy to clipboard operation
zod copied to clipboard

Broken overload in `z.record()`.

Open colinhacks opened this issue 1 year ago • 3 comments

There's a bug in the overloads for z.record() that lets you to pass in an arbitrary schema as the key schema into z.record()...whoops.

const schema = z.record(z.object({ name: z.number() }), z.number());
// no TS errors

The expected behavior is that the first argument should conform to type KeySchema = ZodType<string | number | symbol, any, any>; but it currently doesn't.

In order to fix it I need to remove the "single argument" shorthand: z.record(z.number), which will land in Zod 4.

colinhacks avatar Mar 22 '24 00:03 colinhacks

Did you write it backwards?

image
const User = z.object({ name: z.string() });

const UserStore = z.record(z.string(), User);

LemonAppleMo avatar Mar 22 '24 09:03 LemonAppleMo

I did not. The point is that this code should throw an error when I try to pass a ZodObject as the key, but it doesn't.

colinhacks avatar Mar 22 '24 22:03 colinhacks

@colinhacks looks like this could be fixed like this:

static create<Value extends ZodTypeAny, Params extends RawCreateParams>(
  valueType: Value,
  params?: Params extends ZodTypeAny ? never : Params
): ZodRecord<ZodString, Value>;

Not super ideal but it will complain about it will never if the 2nd param is a ZodTypeAny forcing TS to choose the other overload.

Though if you're removing the single arg variant this would be moot

LiamMartens avatar Apr 27 '24 14:04 LiamMartens