Yup Typescript Union/Intersection-validering


För ett projekt använder jag yup men jag har problem med att få en bra typ från schemat ... I idealfallet skulle jag vilja få en typ som visar att när en egenskap har ett visst värde, måste en annan egenskap vara definierad!

Jag byggde en snabb Codesandbox som visar problemet, men jag postar det här också om du inte vill byta ...

Schemasdefinition som detta

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)
  })
});

Schemas typ

type Schema = yup.InferType<typeof schema>;

Vad jag får:

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

Nu när jag kontrollerar ett objekt som har contactForm: "email" kommer TypeScript fortfarande att klaga på att e-post kan vara odefinierad. För små objekt kan det vara okej, men jag har scheman där flera egenskaper måste vara definierade när en egenskap har ett visst värde, vilket gör att TypeScript känns ganska värdelöst ...

Vad jag vill

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

Är detta inte möjligt med Yup? Om det är möjligt, hur skulle jag behöva definiera schemat?

Relaterade artiklar