Named capture groups let you label the parts of a regex match and retrieve them by name instead of by numeric index. In TS-Rex, everyDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/fajarnugraha37/ts-rex/llms.txt
Use this file to discover all available pages before exploring further.
.capture() call you chain onto a builder is recorded at the type level, so by the time you call .compile() and then .exec(), TypeScript already knows the exact shape of your result — no type assertions, no as string, no guessing.
A simple two-group pattern
The most direct way to see this in action is with a name parser. You build up the pattern by chaining methods, give each group a string identifier, and the result type is inferred automatically.The MatchResult discriminated union
exec() returns a discriminated union on the isMatch boolean. Before you access any captured field you must narrow the type with an isMatch check. TypeScript enforces this — if you try to read result.firstName outside the if block, the compiler will warn you that it might be undefined.
The two branches of the union are:
| Branch | Shape |
|---|---|
| Success | { isMatch: true, match: string, firstName: string, lastName: string } |
| Failure | { isMatch: false, match: null, firstName: undefined, lastName: undefined } |
undefined, so you can safely destructure anywhere — as long as you check isMatch first.
What TypeScript infers
You can inspect the inferred type of a compiled pattern’sexec return directly. After two .capture() calls named 'firstName' and 'lastName', the success branch looks like this:
.capture('name', builder) call merges Record<'name', string> into the running type state via TypeScript’s intersection types. There is zero runtime overhead — the type accumulation happens entirely at compile time through phantom generic parameters on RegexBuilder<TCaptures, TFlags>.
Capture names must be valid JavaScript identifiers. TS-Rex validates names at runtime and throws if you pass something like
'1invalid' or 'my-group'. Stick to names you would use as a variable: camelCase, snake_case, or PascalCase all work.Richer types from multiple captures
Patterns with more captures produce correspondingly richer result types. Here is a date parser that extracts four named groups:Nested captures
You can pass a builder that itself contains.capture() calls as the second argument to an outer .capture(). Both the outer and inner group names are merged into the result type.