`.required()` doesn't remove optional flag from the result of `.nullish()`
The (undocumented) function .required is not working properly for properties defined with .nullish():
const base = z.object({
required: z.string(),
nullable: z.string().nullable(),
optional: z.string().optional(),
nullableOptional: z.string().nullable().optional(),
nullish: z.string().nullish(),
})
const req = base.required()
The resulting inferred type of req is:
{
required: string;
nullable: string | null;
optional: string;
nullableOptional: string | null;
nullish?: string | null | undefined;
}
As you can see, all fields that were defined as .optional() have properly been made non-optional except for the one created using .nullish()
This seems to arise from the fact that .nullish() is defined to return a ZodNullable<ZodOptional<T>> and .required simply returns the outermost ZodOptional without doing any type recursion, and as such it cannot see the optional in that type.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Up
Here's how I solved it: https://github.com/3x071c/lsg/blob/e2a9592ba3ec5103556f2cf307c32f08aeaee32d/app/lib/util/zod.ts
It's inspired from the .required() implementation in the zod source code. Since it has similar semantics, it can be integrated as-is. One major difference is that due to the circumstance of it being an external module, it accepts zod objects as first parameter, not as this (via chaining).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Up
Having the same issue. I've opened a question here.
Having the same issue. I've opened a question here.
Not quite, you removed null values in your example.
Required is defined in typescript and in zod as being the opposite of Partial. So it should keep null, and only remove undefined and ?.