Type-Level RegExp parser, matcher and permutation resolver
npm install type-level-regexp> TypeScript type-level RegExp parser and matcher implemented using template literals.
!Demo

š Try on TypeScript Playground
or see examples in Playground and test folders.
š§ Work In Progress, PRs and issues are welcome š§
1. Add type-level-regexp dependency to your project
``bashUsing pnpm
pnpm i -D type-level-regexp
2. Import
createRegExp function, pass in a RegExp string pattern to it creates a TypedRegExp, passing this TypedRegExp to String.match(), String.matchAll() or String.replace() functions to get fully typed match result.Basic Usage
match result will be fully typed if match against a literal stirng, or shows emumerated results if match against a dynamic string.
`ts
import { createRegExp, spreadRegExpIterator } from 'type-level-regexp'/* string.match() /
const regExp = createRegExp('foO(?b[a-g]r)(?:BAz|(?qux))', ['i'])
const matchResult = 'prefix foobarbaz suffix'.match(regExp) // matching literal string
matchResult[0] // 'foobarbaz'
matchResult[1] // 'bar'
matchResult[3] // show type error
type '3' can't be used to index type 'RegExpMatchResult<...>
matchResult.length // 3
matchResult.index // 7
matchResult.groups // { g1: "bar"; g2: undefined; }/* string.replace() /
const regExp2 = createRegExp('(\\d{4})-.-.')
const replaceResult = '1991-Sept-15'.replace(regExp2, '$ $3, $1')
replaceResult // 'Sept 15, 1991'
/* string.matchAll() /
const regExp3 = createRegExp('c[a-z]{2}', ['g'])
const matchALlIterator = 'cat car caw cay caw cay'.matchAll(regExp3)
const spreadedResult = spreadRegExpIterator(matchALlIterator)
spreadedResult[2][0] // 'caw'
spreadedResult[3].index // 12
const InvalidRegExp = createRegExp('foo(bar')
// TypeScript error: Argument of type 'string' is not assignable to parameter of type 'RegExpSyntaxError<"Invalid regular expression, missing closing \
)\">'
`For TypeScript library authors, you can also import individual generic types to parse and match RegExp string at type-level and combine with your library's type-level features.
`ts
import { ParseRegExp, MatchRegExp } from 'type-level-regexp'type MatchResult = MatchRegExp<'fooBAR42', ParseRegExp<'Foa-z\\d{2}'>, 'i'>
type Matched = MatchResult[0] // 'fooBAR42'
type First = MatchResult[1] // 'BAR'
type RegExpAST = ParseRegExp<'foo(?bar)'>
// [{
// type: "string";
// value: "foo";
// }, {
// type: "namedCapture";
// name: "g1";
// value: [{
// type: "string";
// value: "bar";
// }];
// }]
`
Origin & Notice
The main purpose of this project is to test and demonstrate the possibility and limitations of writing a RegExp parser/matcher in TypeScript's type-level. Note that this may not be practically useful, but rather an interesting showcase.The idea for this project originated while I was working on improving the type hints of string.match and replace in magic-regexp (created by the most inspiring, resourceful, and kind Daniel Roe from Nuxt, definitely check it out if you are working with RegExp and TypeScript!).
As the complexity grows, I start working on this separated repo to increase development speed and try out different iterations. It will be incorporate and use in magic-regexp, and Gabriel Vergnaud's awesome hotscript very soon.
ā¤ļø Testing, feedbacks and PRs are welcome!
Features
- Export
createRegExp function to create aTypedRegExp that replace your original /regex_pattern/ regex object, which can be pass to String.match(), String.matchAll() and String.replace() functions and gets fully typed result.
- Shows RegExpSyntaxError if the provided RegExp pattern is invalid.
- Enhance types of RegExp related String functions (.match, matchAll, .replace...) for literal or dynamic typed string.
- Result of String functions matched exactly as runtime result.
- Support all common RegExp tokens (incl. Lookarounds, Backreferences...etc), quantifiers (incl. greedy/lazy) and (g,i) flags.
- Export helper functions spreadRegExpMatchArray and spreadRegExpIterator to get tuple type of match results and iterators.
- Provide generic type ParseRegExp to parse and RegExp string to AST.
- Provide generic type MatchRegExp to match giving string with a parsed RegExp.
- Provide generic type ResolvePermutation to permutation all possible matching string of given RegExp if possible (due to TypeScript type-level limitation)
- More details please try on TypeScript Playground, or see tests files in Tests and Stackblitz. (examples in index.test-d.ts)
#### Example - type-safe args in replacing function of
string.replace()
!replaceRegexp#### Example - spreaded
string.matchAll() with union of RegExp pattern remain as tuple
!type-level-matchAll-with-union
$3
| Tokens | Description | Support |
| --- | --- | --- |
|
. | Matches any single character. | ā
|
| , ? | Matches zero or more occurrences (Greedy/Lazy). | ā
|
| +, *? | Matches one or more occurrences (Greedy/Lazy). | ā
|
| ?, ?? | Matches zero or one occurrence (Greedy/Lazy). | ā
|
| ^ | Matches the start of a line. | ā
|
| $ | Matches the end of a line. | ā
|
| \s, \S | Matches any whitespace, non-whitespace character. | ā
|
| \d, \D | Matches any digit, non-digit character. | ā
|
| \w, \W | Matches any word, non-word character. | ā
|
| \b, \B | Matches a word-boundary, non-word-boundary. | ā
|
| [abc] | Matches any character in the set. | ā
|
| [^abc] | Matches any character not in the set. | ā
|
| () | Creates a capturing group. | ā
|
| (?:) | Creates a non-capturing group. | ā
|
| (? | Creates a named-capturing group. | ā
|
| \| | Matches either the expression before or after the vertical bar. | ā
|
| {n} | Matches exactly n occurrences. | ā
|
| {n,} | Matches at least n occurrences. | ā
|
| {n,m} | Matches between n and m occurrences. | ā
|
| (?=), (?!) | Positive/Negative lookahead. | ā
|
| (?<=), (? | Positive/Negative lookbehind. | ā
|| Flags | Description | Support |
| --- | --- | --- |
| g | Global matching (matches all occurrences). | ā
|i
| | Case-insensitive matching. | ā
|
- Clone this repository
- Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)pnpm install
- Install dependencies using pnpm dev`
- Run interactive tests using
Made with š„ and ā¤ļø
Published under MIT License.
[npm-version-src]: https://img.shields.io/npm/v/type-level-regexp?style=flat-square
[npm-version-href]: https://npmjs.com/package/type-level-regexp