[JS/TS] Don't declare regex with flags in an object property
Tags: javascript, typescript, is, validation
Published: 2023-03-23 18:33:12

While I was writing the package: [thiis](https://github.com/Karbashevskyi/thiis) I found one problem with regex when I tried add a new property to exist object with regex value.

When I wrote the new package's `is.upperCase()` method, I used a regular expression to find lowercase characters, and if found, it's an error because we want to check if the text is only uppercase, regardless of whether other characters are present, e.g. special characters.

"Bad" regex: `/[a-z]/g`
"Good" regex: `/[a-z]/`

_If you are interested in why this is the logic, then write in the comments so that I write a post about it, or write about what else you are interested in knowing._

So, the problem... 
The problem was only with `"null"` **word**, method passed the word as correct but it isn't, I don't why but I know how to solve the problem, let me show.

Before, I'll show you what unit tests look like.

This is unit test with cases:

```typescript
    it.each([
        { value: 'a1B2c3d4e5f6g' },
        { value: 'a1B2c3d4e5f6g' },
        { value: 'inCamelCase' },
        { value: 'undefined' },
        { value: 'null' },
    ])('is.upperCase: Should false for $value', ({value}) => {
        expect(is.upperCase(value)).toBe(false);
    });
```

And this is the problem, there are three screens which show you: config, method and how unit test passed cases:

1. Config

```typescript
export const isConfig = {
  useGlobalContext: true,
  error: {
    enabled: true,
  },
  regex: {
    lowerCase: /[a-z]/g, // Example how to use: !isConfig.regex.lowerCase.text('HELO WORLd') => false
  },
};
```

As you can see, the "bad" regex is declare in property of config object.

2. Method

```typescript
import {isConfig} from '../config';
import {StringMethod} from './string.method';

export function UpperCaseMethod(argument: unknown): argument is string {
    if (StringMethod(argument)) {
        return !isConfig.regex.lowerCase.test(argument);
    }
    return false;
}
```


3. Unit test: passed cases

![Unit test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0k4x54r133lummitljnw.png)

And as you can see, we expect the result to be false, but it is true!

So, the solution to the problem:

First of all I need to check if the regex is correct, maybe I'm missing something, we can just move the regex into a method and call the test method there to test the argument and see if it works correctly.


```typescript
import {isConfig} from '../config';
import {StringMethod} from './string.method';

export function UpperCaseMethod(argument: unknown): argument is string {
    if (StringMethod(argument)) {
        return !/[a-z]/g.test(argument);
    }
    return false;
}
```

The result:

![Unit tests](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vwpm6q9zoe23ext48guo.png)

And that's what I don't know why it works correctly, the only difference is when I call the regex from the property and direction.

Next, I will try to remove the `g` from the regular expression and now you can see the result:

1. Config

```typescript
export const isConfig = {
  useGlobalContext: true,
  error: {
    enabled: true,
  },
  regex: {
    lowerCase: /[a-z]/, // Example how to use: !isConfig.regex.lowerCase.text('HELO WORLd') => false
  },
};
```

2. Method

```typescript
import {isConfig} from '../config';
import {StringMethod} from './string.method';

export function UpperCaseMethod(argument: unknown): argument is string {
    if (StringMethod(argument)) {
        return !isConfig.regex.lowerCase.test(argument);
    }
    return false;
}
```

3. Unit test: passed cases

![Unit tests](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vwpm6q9zoe23ext48guo.png)

And as you can see, the result is good :)

Conclusion:
Be careful using regular expressions in object properties!

Thanks for reading the article!