Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegExp constructor ignoring given flags as second argument leading to TS errors #58993

Closed
anthonyLock opened this issue Jun 24, 2024 · 7 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@anthonyLock
Copy link

anthonyLock commented Jun 24, 2024

🔎 Search Terms

error TS1530: Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.

🕗 Version & Regression Information

  • This is a crash
  • This changed between versions 5.4.5 and 5.5

⏯ Playground Link

https://www.typescriptlang.org/play/?declaration=false&target=8&ts=5.5.2&noLib=false#code/MYewdgzgLgBA5gUygSTASymghgGwjAXhgAoBXCBAJwgDksBbBALhmkrTDgEoW2O5CAPhgBvAFAwYOJDEpwAHoRhgEAdxgAlBHACi8gA7EA9MQA6+kQBkAviICM1ruavWA1EYA0MAERxS3rgBuMQkpGQ4MbDwlAG0AOgTyKloGBDj6LChgAAsAQRwcYjl5LgBdGAAfCpgY0uDQyiRSSjASUMliCMxcCDiIbLQAMyhiLgB+OJi7cqqfAJhXEi6o3v0QQ3HJ6crq7wDQrjioEABVfX0qAGEsClHg63rQSFhEFHRuvBoQHUpKEGolGQKNQ6IxeFB2JweKwIfwhKJQk9oLIFEoTM4bPZHBi3EY-MFJNJYMserEEnEkiDUulMjl8oVimUdjU6iFJI0oM1WsR2kt3is+gNhqMJlMZrt5otOvyenE1htRdtZnsuAcjqdzlcbgg7mIHiEkS8kKhIj0vj8-tQAEyAykpMEwyHccFO+HiQkyYpKZRqTTaPSGADkZhxWKcONcga8gb8gdVoSJMBJ0SI8USwPtaQyWTyBSKCiZs1q9XZTRabUkHWTvX6QxGmzFzJVCz5prwcvWIq24rmqskh2OZwulGutyCevqYiRIGkcRwIDgxFeJo+EGI3myCAKIBgqn+OAAJgFVdPZ-PF8uZZ9vr9-muN1v5zBSOgAG7JBDHqfgCAztLnpdjSvWgb0tCArXXTdt3gXAsHkABPY8gA

💻 Code

 let rgx = new RegExp(/(\p{L}{1})\p{L}+/, "gu");

🙁 Actual behavior

This is giving the error Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set. even though the unicode flag is provided

🙂 Expected behavior

The regex compile testing that was brought in 5.5 should take into account the flags given in the new RegExp constructor

Additional information about the issue

This only occurs when adding extra flags to the constructor ( getInitials in the playground link) if you either create a regex directly (getInitialsNoErrors) or give the regex as a string (getInitialsNoErrors2) then it compiles ok

@nmain
Copy link

nmain commented Jun 24, 2024

Why not just write this as /(\p{L}{1})\p{L}+/gu?

@anthonyLock
Copy link
Author

@nmain if you change the target to es5 then you get the error This regular expression flag is only available when targeting 'es6' or later. Its not effecting me right now as I have changed it for the string approach let rgx = new RegExp('(\\p{L}{1})\\p{L}+', 'gu') but its a bug regardless, and will cause confusion for others.

@jcalz
Copy link
Contributor

jcalz commented Jun 24, 2024

"This is a crash" That means the compiler itself crashed. If the errors you're seeing are in your own code, or in code being compiled, it's not a crash. Only if the errors are a stack trace of the compiler code itself is it a crash.


This doesn't look like a bug to me. The problem is in /(\p{L}{1})\p{L}+/ itself. For that to be a valid regex it needs to have the u (or v) flag, as those unicode property value expressions are only supported in Unicode-aware mode. Certainly the equivalent code:

const re = /(\p{L}{1})\p{L}+/; // error
// later
let rgx = new RegExp(re, "gu");

should be an error, right? Because the thing you assigned to re is not valid. The fact that you later fix it doesn't change that. So are you saying there should be a carve-out for when invalid regexes are created inline? I'd think it would be better never to write /(\p{L}{1})\p{L}+/ in the first place, and just write /(\p{L}{1})\p{L}+/u, at least, which makes it valid. Once you do that the error goes away:

new RegExp(/(\p{L}{1})\p{L}+/u, "gu"); // okay

Of course then there doesn't seem to be much benefit over writing /(\p{L}{1})\p{L}+/gu in the first place. Indeed, making a regex only to throw it away while building another regex seems weird to me. If I saw someone write const x = [...[1, 2, 3], 4] instead of const x = [1, 2, 3, 4], I'd be very puzzled. Seems like the same thing here.

@nmain
Copy link

nmain commented Jun 24, 2024

if you change the target to es5 then you get the error This regular expression flag is only available when targeting 'es6' or later.

That is correct. These features are not available in es5. If this works at runtime:

new RegExp(/(\p{L}{1})\p{L}+/, "gu").test('AB') === true

then the JS engine you are targeting is not es5.

and will cause confusion for others

I disagree. The regex /(\p{L}{1})\p{L}+/, without the u flag, is extremely confusing:

/(\p{L}{1})\p{L}+/.test('p{L}p{L}}}}}}') === true

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jun 24, 2024
@RyanCavanaugh
Copy link
Member

Agree with prior commentors.

There's also the option of new RegExp("(\\p{L}{1})\\p{L}+", "gu")

@anthonyLock
Copy link
Author

@jcalz @nmain

Thanks for the information. I have closed the issue, if an admin wants to delete the issue feel free. I didn't realise that regex in that form was not supported in es5. Somewhere in my project between the setup and use of babel,nextjs etc... there is a configuration issue.

Quick question just to improve my own knowledge, please could you explain the use case of using the second variable in the constructor for RegExp and when would you would you want to use it instead of adding it into the first input?

@nmain
Copy link

nmain commented Jun 25, 2024

@anthonyLock I think the RegExp constructor is primarily for creating dynamic regexes, whose content is not known at compile-time. Situations like this:

function escape(s: string) {
	return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
const searchValue: string = getSearchValueFromInputField();
const escaped = escape(searchValue);
const testRegex = new RegExp(escaped, "i");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants