question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. Itย collects links to all the places you might be looking at while hunting down a tough bug.

And, if youโ€™re still stuck at the end, weโ€™re happy to hop on a call to see how we can help out.

String#matchAll should return iterable of RegExpExecArray instead of RegExpMatchArray

See original GitHub issue

TypeScript Version: 3.7 (issue is with lib typing)

Search Terms: regex, matchall, es2020

Code

const matches = Array.from('xxx'.matchAll(/x/g));
matches[0].index; // TS reports index may be undefined, when it should always be defined

Currently matchAll returns an iterable of RegExpMatchArray. However, the index and input properties on RegExpMatchArray are optional because String#match returns a match object without those if the regex has the global flag (https://github.com/microsoft/TypeScript/issues/35157).

matchAll on the other hand doesnโ€™t have the same behavior, so it should use RegExpExecArray where both of those properties are non-optional (or maybe create a RegExpMatchAllArray type)

> Array.from('xxx'.matchAll(/x/g)) 
[
  [ 'x', index: 0, input: 'xxx', groups: undefined ],
  [ 'x', index: 1, input: 'xxx', groups: undefined ],
  [ 'x', index: 2, input: 'xxx', groups: undefined ]
]
> Array.from('xxx'.matchAll(/a/g)) 
[]
> Array.from('aaa'.matchAll(/x/g)) 
[]

Expected behavior:

input and index on the match objects are not optional

Actual behavior:

TS reports that input and index may be optional

Playground Link: (Canโ€™t use playground since lib cannot be configured)

Related Issues: https://github.com/microsoft/TypeScript/pull/30936 introduced String#matchAll

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:23
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

8reactions
clemyancommented, Apr 30, 2021

According to the spec, String#matchAll actually executes with the semantics of RegExp#exec instead of String#match.

So, OP is correct, the return type of String#matchAll should be IterableIterator<RegExpExecArray>, not the current IterableIterator<RegExpMatchArray>.

5reactions
sholladaycommented, May 24, 2020

A regex given to .matchAll() will always be global. JavaScript throws an error if you attempt to pass it a non-global regex. Thus, unlike the return value of .match(), the return value of .matchAll() is always guaranteed to have .index and .input.

I think the types for .match() make sense given that TypeScript has a limited understanding of regex flags and .match() has a return type that is conditional on those flags, but the flags and limitations surrounding them are irrelevant to .matchAll(), as the only possible return value from .matchAll() is a type where .index and .input are required (always present and non-nullable).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does the new "matchAll" in Javascript return an iterator ...
When using the iterator, the regex will only evaluate the next match in the string once the prior match has been iterated over....
Read more >
String.prototype.match() - JavaScript - MDN Web Docs
If the g flag is used, all results matching the complete regular expression will be returned, but capturing groups are not included.
Read more >
Letting RegExp method return something iterable? - ES Discuss
Would it make sense to create similar methods that return something iterable, so that for-of can ... That could be an Array, rather...
Read more >
TypeScript: src/compiler/utilities.ts - Fossies
iterResult.done; iterResult = iterator.next()) { 130 const result = callback(iterResult.value); 131 if (result) { 132 return result;ย ...
Read more >
ES2020: `String.prototype.matchAll` - 2ality
match() plus /g returns an iterable (an Array) over which you can iterate as often as you want. Implementing .matchAll() # .matchAll() could...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found