colinhacks / zod

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

ZodObject with generic key (i.e. [key: string]: xx) and specific key (i.e. {debug: xx}) don't _seem_ to work as expected #3607

Open aliak00 opened 4 months ago

aliak00 commented 4 months ago

Hey, I'm trying to take type that is defined like:

type A = {
  [x: string]: AllowedZodType;
  debug: z.ZodDefault<z.ZodBoolean>; // One of the allowed zod types
};

And convert it to a ZodObject, which I can later use z.infer on to get a native type out. I'm having some problems though. First this is how my AllowedZodType is defined (it's for defining command arguments schemas for a CLI)

type BaseZodType =
  | z.ZodString
  | z.ZodNumber
  | z.ZodBoolean
  | z.ZodEnum<[string, ...string[]]>
  | z.ZodRecord<z.ZodString, z.ZodString | z.ZodNumber>
  | z.ZodArray<z.ZodString | z.ZodNumber, 'many'>;

type NativeType = z.infer<BaseZodType> | undefined;

type WrappedZodType = z.ZodDefault<BaseZodType> | z.ZodOptional<BaseZodType>;

type AllowedZodType = BaseZodType | WrappedZodType | z.ZodEffects<WrappedZodType | BaseZodType, unknown, NativeType>;

So what I would like to do is is take type A defined above, and:

type X = z.ZodObject<A>
type Y = z.infer<X>

// Where Y ends up looking like:
type Y = {
  [x: string]: NativeType;
  debug: boolean;
}

But what I actually get is:

type X = z.ZodObject<aaa, z.UnknownKeysParam, z.ZodTypeAny, {
    [x: string]: unknown;
    debug?: unknown;
}, {
    [x: string]: NativeType;
    debug?: unknown;
}>

type Y = {
    [x: string]: unknown;
    debug?: unknown;
}

I'm thinking there might be something I can use or do, or is this just being interpreted incorrectly by zod's utility types or am I doing something totally dumb?

Thank you!