Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nullableInput #1146

Closed
wants to merge 1 commit into from
Closed

Add nullableInput #1146

wants to merge 1 commit into from

Conversation

ArnaudBarre
Copy link

Hello and thanks for this lib that has completely changed my way of doing client and server side validations.

One pattern that I'm missing is the ability to change the input type while keeping the output type strict. This PR includes my most needed one: Adding nullable type on the input.

Why?

I'm using schema["_input"] type to strongly type the initial values of my form, and some values are required but can't have a meaningful default (like choosing an entity from a list) and are set to null.

Current solution

export const addNullInput = <A, B, C>(value: ZodType<A, B, C>) =>
  value
    .nullable()
    .refine((v) => v !== null, "Required")
    .transform((v) => v!);

The problem is it creates some runtime and type-checking overhead that could be simplified with a support from the lib.

Related

#213

@netlify
Copy link

netlify bot commented May 17, 2022

Deploy Preview for guileless-rolypoly-866f8a ready!

Name Link
🔨 Latest commit 1dfbbf9
🔍 Latest deploy log https://app.netlify.com/sites/guileless-rolypoly-866f8a/deploys/6283ca7dcfdda8000854d325
😎 Deploy Preview https://deploy-preview-1146--guileless-rolypoly-866f8a.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@colinhacks
Copy link
Owner

colinhacks commented May 23, 2022

Interesting use case! This was a tricky one but I found a good approach. It recently because possible to add issues inside transforms, similar to superRefine, which unlocks a cleaner approach to this problem:

  const noNull = <T>(val: T | null, ctx: z.RefinementCtx) => {
    if (val === null) {
      ctx.addIssue({
        code: z.ZodIssueCode.invalid_type,
        expected: z.ZodParsedType.string,
        received: z.ZodParsedType.null,
        message: "Required",
      });
    }
    return val!;
  };
  const schema = z.number().nullable().transform(noNull);

You can define noNull somewhere and import it wherever it's needed. Because it's generic, it can be used on any nullable schema and the input/output types will be what you expect. I think this is cleaner than adding an additional method.

@colinhacks colinhacks closed this May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants