zod icon indicating copy to clipboard operation
zod copied to clipboard

Inferred type of Object catchall with boolean is empty object

Open valeneiko opened this issue 1 year ago • 9 comments

const schema = z.object({}).catchall(z.boolean());
type T = z.output<typeof schema>;
//   ^? {}

I am expecting type T = Record<string, boolean>, but inferred type is empty object instead.

valeneiko avatar Dec 11 '23 17:12 valeneiko

Are you only wanting to report the bug? or are you looking for a temp workaround?

JacobWeisenburger avatar Dec 11 '23 17:12 JacobWeisenburger

Was just reporting a bug.

I am currently using this workaround:

z.object({}).catchall(z.boolean()) as z.ZodObject<
  z.ZodRawShape,
  'strip',
  z.ZodBoolean,
  Record<string, boolean>
>

valeneiko avatar Dec 12 '23 17:12 valeneiko

This is intentional. Unfortunately the runtime behavior of .catchall() does not agree with TypeScript's interpretation of index signatures. For instance you can't declare this type:

type A = { 
  name: string;
  [k:string]: number
};

The [k: string] (or the Record<> type you proposed) applies to all elements of the object type, including named properties. It isn't a "catchall" in the way Zod treats it. This is why .catchall() doesn't change the inferred type. There's no syntax in TypeScript to represent a "catchall index signature".

colinhacks avatar Mar 14 '24 23:03 colinhacks

@valeneiko Consider z.record for your specific use case.

colinhacks avatar Mar 14 '24 23:03 colinhacks

@colinhacks wouldn't intersecting an index signature with an object capture the semantics of .catchall()?

type X = {
    x: number
} & {
    [key: string]: boolean
};

type Q1 = X['x'];
//   ^? type Q1 = number

type Q2 = X['y'];
//   ^? type Q2 = boolean

Playground Link

Nvm, just realized the type is not actually usable, just displays like that.

valeneiko avatar Mar 15 '24 23:03 valeneiko

Nvm, just realized the type is not actually usable, just displays like that.

Indeed, this is exactly what threw me off in the first place 😅

colinhacks avatar Mar 19 '24 23:03 colinhacks

Apologies, this actually is a bug. See my reply here: https://github.com/colinhacks/zod/pull/3282

colinhacks avatar Mar 21 '24 23:03 colinhacks

Fixed in Zod 3.23

colinhacks avatar Apr 21 '24 23:04 colinhacks