Alternation means “match this pattern or that pattern.” In raw regex you writeDocumentation 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.
a|b. In TS-Rex you chain .or(otherBuilder). What makes TS-Rex’s approach distinctive is that the type system models the mutual exclusivity of the two branches: if branch A matched, branch B’s captures are undefined, and vice versa. This is represented by wrapping both sides in Partial.
A basic alternation
The simplest case has each branch containing a single named capture.(?:(?<a>A)|(?<b>B)). At runtime, a match against 'A' populates a and leaves b as undefined. A match against 'B' does the opposite.
How .or() computes the type
The.or() method signature on RegexBuilder is:
Partial. This is the correct model because the regex engine can only take one branch at a time — you cannot know at compile time which branch succeeded, so all captures from both branches become optional (string | undefined).
After an isMatch check you still have to narrow further if you want to treat a specific capture as definitely present:
Building character ranges with .or()
.or() is also the correct way to compose character class alternatives when you need type-safe range composition. The auto-escaping rules mean you cannot inject raw range syntax like a-z into .anyOf() — instead you chain .range().or().
.capture(), all TCaptures states are Record<never, never> and the resulting Partial wrapping has no visible effect on the final type. The composition is purely structural.
A more complex alternation with multiple branches
You can chain.or() more than once to build multi-branch alternations. Each call wraps the accumulated left side in Partial again.
The compiled regex for
.or() uses non-capturing group wrapping: (?:left|right). The outer group ensures the alternation is properly delimited when other tokens follow.Narrowing after .or()
Since all captures from an alternation arestring | undefined, you narrow them the same way you would any optional property in TypeScript — a simple inequality check against undefined.
Partial intersection — but the runtime behaviour is correct, and the narrowing pattern above is safe and idiomatic.