Search code examples
javascriptregexyup

Yup schema validation: Exclude a certain pattern in the method '.matches()'


I want to make sure users don't fill in their username (pattern is a upercase or lowercase u, followed by 7-10 digits: U0000000)

In the following example, the regex itself does work. However in conjunction with the .matches() method it does not validate the field.

const schema = Yup.object()
  .shape({
    myField: Yup.string()
      .matches(/.*\d/, 'Should contain a digit') // <- this works
      .matches(/(?!.*[uU]\d{7,10})/, 'Should not contain a user ID') // <- this does not
  });

Solution

  • Turns out that matches will only validate an invalid error if the Regex you provide returns positive.

    If you want to validate on a negative 'match' (a.k.a. not operator regex match), you can use the .test() method.

    In the documentation it's not mentioned under string, but under mixed (source):

    mixed.test(name: string, message: string | function, test: function): Schema
    

    So in my example I ended up with:

    const containsDeviceId = (string) => /d\d{7,10}/.test(string);
    const schema = Yup.object()
      .shape({
        myField: Yup.string()
          .matches(/.*\d/, 'Should contain a digit')
          .test(
            'Should not contain a user ID',
            'Should not contain a user ID',
            (value) => !containsDeviceId(value)
          ),
    

    Hope this helps someone.