Search code examples
typescriptvalidationzod

Wrong type inference when using Zod


In this validation schema, if the validation passes, the type of email will always be a string. However, for some reason typescript is telling me that email either returns a string or false. I do not see any possibility that email could ever return false, am I missing something?

To elaborate: When I use z.string().email(), I am guaranteeing that the outcome is indeed a valid email, otherwise the validation will fail and the value will not be passed to the transform > normalizeEmail part. So the final result must indeed be an string.

import { z } from "zod";
import validator from "validator";

const email = (maxChar: number) =>
  z
    .string()
    .max(maxChar)
    .email().transform((value) => validator.normalizeEmail(value))
    ;

Solution

  • validator.normalizeEmail returns false if the email is not valid (which is a strange design choice if you ask me). Since you are already checking if it is a valid email using Zod, I would opt for an assertion:

    const email = (maxChar: number) =>
      z
        .string()
        .max(maxChar)
        .email().transform((value) => validator.normalizeEmail(value) as string)
        ;
    

    Playground