-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Prevent error 2488 Type 'RegExpMatchArray | null' must have a '[Symbol.iterator]()' method that returns an iterator.
when match is guaranteed
#47808
Comments
When you're 100% certain it cannot be null, you can use |
The correct way is to assign the result the result to a temporary and check that, as you did in your workaround. I personally would never write the first snippet, as calling a method twice that you know is going to return the same thing both times just creates extra work for the computer unnecessarily. |
Agree with that, but the resulting code is less readable in if-else-if statements if temporary variables are created: const res1 = string.match(re1);
if (res1) {
const [g1] = res1;
// ...
} else {
const res2 = string.match(re2);
if (res2) {
const [g2] = res2;
// ...
}
} Vs. matching again: if (string.match(re1)) {
const [g1] = string.match(re1)!;
// ...
} else if (string.match(re2)) {
const [g1] = string.match(re2)!;
// ...
} A temporary let matchResult;
if (matchResult = string.match(re1)) {
const [g1] = matchResult;
// ...
} else if (matchResult = string.match(re2)) {
const [g1] = matchResult;
// ...
} but that leads to a linting error about using the assignment as a comparison. |
@tredondo How are you suggesting this be solved, exactly? Are you suggesting that TS should type-guard when you repeat function calls with the same arguments? If so, this isn't true in the general case: function myMatch() {
if(Math.random() > .5) {
return [1,2,3]
}
return null;
}
if(myMatch()) {
// If TS assumes `myMatch()` returns `[1,2,3]` then this compiles... but it's obviously not safe
const [one, two, three] = myMatch()
} Are you suggesting that TS should have special case-logic for treating The only way I could see this being solved without either hard-coded exceptions (or big losses of type-safety) would be to add entirely new concepts to the language (e.g. "pure" functions that always return the same output for their inputs, identified at the type level). So, yeah, I think you're best off looking for a solution in your own code. If you think the |
That's what I was thinking, if it's not an awkward solution. |
Yeah, I think that'd be an awkward solution, I don't think the TS team wants to add hard-coded compiler exceptions for specific APIs. I'm pretty sure there aren't any existing examples of compiler-baked exceptions for build-in APIs (even though there's quite a few places where they theoretically could). Opening the door to these sort of hard-coded exceptions would potentially add a lot of complexity, and I think it overall makes the language more confusing if some special functions don't "play by the same rules" as the rest of the language. I think there'd have to be a significant benefit, and I don't think "it avoids an extra variable assignment / violating a linter rule" or "I think this is slightly cleaner with less indentation" meets that bar. |
const [digits] = string.match(RE) || [];
if (digits) {
console.log(digits);
} Straight forward, no duplicate computations, type-safe (if |
We don't hardcode specific method behavior into the compiler; this makes it impossible for users to write functions that behave the same way as built-ins, which is a really frustrating state to be in. A possible avenue would be #7770 - two identical pure function calls could be treated as "the same" for purposes of narrowing, but even that isn't really sufficient here, since RegExps themselves are not immutable. You would have to somehow know that |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Suggestion
π Search Terms
Type 'RegExpMatchArray | null' must have a 'Symbol.iterator' method that returns an iterator.
string.match
null guard
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
TypeScript could infer that in the branch of an
if (string.match(RE)) { ... }
,string.match(RE)
won't be null.π Motivating Example
When assigning the results of string.match() to several variables via array destructuring, we must first ensure that
.match()
didn't returnnull
. If the regexp is constant and not performance-sensitive, this can be also done as follows:Currently, tsc doesn't detect that
string.match(RE)
won't be null in theif
branch.π» Use Cases
Trying to assign the result of a string.match to several variables, using array destructuring.
A workaround is to create an intermediary variable for the match results:
Another workaround is to use try/catch around the
match()
.The text was updated successfully, but these errors were encountered: