...

ts-regexp

A strictly typed & minimal RegExp wrapper.
github-icon
GitHub
166star-icon
Created 20 days ago, last commit 4 days ago
Number of contributors not available
41 commits
Stars added on GitHub, per day, on average
Yesterday
+54star-icon
Last week
+17.7
star-icon /day
npmPackage on NPM
Monthly downloads on NPM
0
0
0
0
0
0
0
0
0
0
0
8
9
10
11
12
1
2
3
4
5
6
7
2024
2025
No dependencies
README

ts-regexp

npm version npm monthly downloads

A strictly typed & minimal RegExp wrapper.

const groups1 = new RegExp('^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$', 'g').exec('2000-10-24')!.groups;
//      ⤴ '{ [key: string]: string; } | undefined' 🤮
const groups2 = typedRegExp('^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$', 'g').exec('2000-10-24')!.groups;
//      ⤴ '{ year: string, month: string, day: string }' 🥰

▶ Try it in the TypeScript Playground

🚀 Setup

  1. Install ts-regexp
# Using npm
npm install ts-regexp

# Using yarn
yarn add ts-regexp

# Using pnpm
pnpm add ts-regexp
  1. Then import typedRegExp:
import { typedRegExp } from 'ts-regexp';

🧩 Usage

Basic Usage

Import and use typedRegExp just like the native RegExp constructor:

import { typedRegExp } from 'ts-regexp';

const datePattern = typedRegExp('(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})');
const emailPattern = typedRegExp('^(?<local>[a-z0-9._%+-]+)@(?<domain>[a-z0-9.-]+\.[a-z]{2,})$', 'i');

The function signature is:

typedRegExp(pattern: string, flags?: string)

Note: typedRegExp returns a plain object, not a RegExp instance.

Standard RegExp Methods

All standard RegExp methods work exactly as expected, but with equivalent or improved typing:

const pattern = typedRegExp('(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})', 'gid');

// Standard methods
pattern.exec('2000-10-24')!.groups;  // { year: string; month: string; day: string; }
pattern.test('2000-10-24');  // boolean

// Access RegExp properties
pattern.source;  // "(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})"
pattern.flags;   // "dgi"
pattern.global;  // true
pattern.sticky;  // false
//  ...

Regex-first Methods

Each RegExp-related string.prototype method is available as ${MethodName}In with equivalent or improved typing:

const datePattern = typedRegExp('(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})');
const text = '1976-11-21';

// Instead of: text.match(pattern)
const match = datePattern.matchIn(text); // typed match

// Instead of: text.replace(pattern, replacement)
const formatted1 = datePattern.replaceIn(text, '$<day>/$<month>/$<year>');
const formatted2 = datePattern.replaceIn(text, (match, year, month, day, offset, string, groups) => `${groups.day}/${groups.month}/${groups.year}`); // typed arguments

// Other inversed methods
datePattern.searchIn(text);    // like text.search(pattern)
datePattern.splitIn(text);     // like text.split(pattern)

Global Flag Methods

When using the global (g) flag, additional methods become available:

const digitPattern = typedRegExp('\\d', 'g');

// Only available with 'g' flag
digitPattern.matchAllIn('1973-12-08');     // like text.matchAll(pattern)
digitPattern.replaceAllIn('123-456', '#'); // like text.replaceAll(pattern, replacement)

Advanced Usage

If you need access to the underlying RegExp instance:

const pattern = typedRegExp('\\d+');
const nativeRegExp = pattern.regExp; // Regular RegExp instance

✨ Features

  • ✅ Strictly typed named & unnamed capture groups
  • ✅ Supports contextual awareness
  • ✅ Parses:
    • nested groups
    • different group types (non-capturing, lookarounds, named captures, etc.)
    • alternation
    • character classes and escaped characters
  • ✅ Infers group optionality from quantifiers (?, *, {n,m})
  • ✅ Validates flags
  • ✅ Supports dynamic (non-literal) pattern + flag inputs

📘 API

📋 Planned

For now, refer to Examples or Usage