'Yup Typescript Union/Intersection Validation

For a project I use yup but I am having problems getting a good type from the schema ... Ideally I'd get a Type that shows when a Property has a certain Value, another property has to be defined!

I built a quick Codesandbox that shows the problem but I post it here too if you don't want to switch ...

Schema Definition like this

const schema = yup.object({
  contactForm: yup
    .mixed<"phone" | "email">()
    .required()
    .oneOf(["email", "phone"]),
  email: yup.string().when("contactForm", {
    is: "email",
    then: (schema) => schema.required().email(),
    otherwise: (schema) => schema.transform(() => undefined)
  }),
  phone: yup.string().when("contactForm", {
    is: "phone",
    then: (schema) => schema.required(),
    otherwise: (schema) => schema.transform(() => undefined)
  })
});

Schema Type

type Schema = yup.InferType<typeof schema>;

What I get:

type Schema = {
    contactForm: "email" | "phone";
    email: string | undefined;
    phone: string | undefined;
}

Now when I check an Object which has the contactForm: "email" TypeScript will still complain that email might be undefined. For small Objects that might be okay, but I have schemas where multiple properties need to be defined when a property has a certain value which makes TypeScript feel kind of useless ...

What I want

type Schema = {contactForm: "email"; email: string} | {contactForm: "phone"; phone: string};

Is this not possible with Yup ? If it is possible, how would I need to define the Schema ?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source