From b14a3ba4cee5516af5443ae0e50de6954a32e74d Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 16 Apr 2022 21:50:12 +0530 Subject: [PATCH 1/4] fix: wraps nested groups in partial --- src/index.ts | 8 +++++--- tests/regex.test.ts | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0c59672..8a6f4f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,9 +22,11 @@ export type RegExCaptureResult = ? { [k in key]?: string } & RegExCaptureResult : { [k in key]: string } & RegExCaptureResult : never - : Re extends `${infer _}(?<${infer rest}` - ? RegExCaptureResult<`(?<${rest}`> - : {}; + : Re extends `(${infer group})?${infer rest}` | `(${infer group})*${infer rest}` + ? Partial> & RegExCaptureResult + : Re extends `${infer _}(?<${infer rest}` + ? RegExCaptureResult<`(?<${rest}`> + : {}; export type RegExMatchResult = { matched: boolean; diff --git a/tests/regex.test.ts b/tests/regex.test.ts index e787264..345014e 100644 --- a/tests/regex.test.ts +++ b/tests/regex.test.ts @@ -27,6 +27,12 @@ describe('TypedRegEx', () => { expect(result).not.toBeNull(); expect(result?.name).toBe('r'); }); + + it('should do stuff', () => { + const r = TypedRegEx('((?\\w+))?', 'gi'); + const result = r.captures('word'); + console.log(result); + }); }); describe('#captureAll', () => { From 1005419ed10b1cf9b0c23ff7e318d2c44bdabf6d Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 16 Apr 2022 21:54:41 +0530 Subject: [PATCH 2/4] fix: fixes lookup for group --- src/index.ts | 4 ++-- tests/regex.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8a6f4f0..7878c36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,8 +24,8 @@ export type RegExCaptureResult = : never : Re extends `(${infer group})?${infer rest}` | `(${infer group})*${infer rest}` ? Partial> & RegExCaptureResult - : Re extends `${infer _}(?<${infer rest}` - ? RegExCaptureResult<`(?<${rest}`> + : Re extends `${infer _}(${infer rest}` + ? RegExCaptureResult<`(${rest}`> : {}; export type RegExMatchResult = { diff --git a/tests/regex.test.ts b/tests/regex.test.ts index 345014e..67cb1b6 100644 --- a/tests/regex.test.ts +++ b/tests/regex.test.ts @@ -28,8 +28,8 @@ describe('TypedRegEx', () => { expect(result?.name).toBe('r'); }); - it('should do stuff', () => { - const r = TypedRegEx('((?\\w+))?', 'gi'); + it('should check for nested groups', () => { + const r = TypedRegEx("^\\w+(@(?[a-z0-9-_.]+))?$", "gi"); const result = r.captures('word'); console.log(result); }); From be33ae447ae1385a6cefb9fa068dcab3ca3c6a3e Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 16 Apr 2022 22:27:44 +0530 Subject: [PATCH 3/4] feat: adds test assertions for types --- tests/regex.test.ts | 22 ++++++++++++++++++++-- tsconfig.json | 6 ++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/regex.test.ts b/tests/regex.test.ts index 67cb1b6..1403e38 100644 --- a/tests/regex.test.ts +++ b/tests/regex.test.ts @@ -1,5 +1,8 @@ import { TypedRegEx } from '../src/index'; +type Equals = [A] extends [B] ? [B] extends [A] ? true : false : false; +const assert_type = () => true as T; + describe('TypedRegEx', () => { describe('#captures', () => { it('should extract year/month/day groups', () => { @@ -9,6 +12,8 @@ describe('TypedRegEx', () => { expect(result?.year).toBe('2020'); expect(result?.month).toBe('12'); expect(result?.day).toBe('02'); + + assert_type>(); }); it('should extract optional groups', () => { @@ -17,6 +22,8 @@ describe('TypedRegEx', () => { expect(result).not.toBeNull(); expect(result?.name).toBe('bar'); + assert_type>(); + // no match case expect(r.captures('hello world')?.name).toBeUndefined(); }); @@ -26,12 +33,17 @@ describe('TypedRegEx', () => { const result = r.captures('foobar'); expect(result).not.toBeNull(); expect(result?.name).toBe('r'); + + assert_type>(); }); it('should check for nested groups', () => { const r = TypedRegEx("^\\w+(@(?[a-z0-9-_.]+))?$", "gi"); - const result = r.captures('word'); - console.log(result); + const result = r.captures('word@0.1.2'); + expect(result).not.toBeNull(); + expect(result?.version).toBe('0.1.2'); + + assert_type>(); }); }); @@ -70,11 +82,15 @@ describe('TypedRegEx', () => { day: '02', }, }); + + assert_type>() }); it('should return matched: false if string doesnt match pattern', () => { const result = dataRegex.match('2020-12'); expect(result).toEqual({ matched: false }); + + assert_type>() }); }); @@ -129,6 +145,8 @@ describe('TypedRegEx', () => { const result = r.captures('foobar'); expect(result).not.toBeNull(); expect(result?.name).toBe('ar'); + + // assert_type>(); }); }); }); diff --git a/tsconfig.json b/tsconfig.json index 2d153a3..b6528cb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,8 @@ { "compilerOptions": { - "moduleResolution": "node", - "target": "es5", - "module":"es2015", - "lib": ["es2020"], + "lib": ["esnext", "es2021"], "strict": true, + "alwaysStrict": true, "sourceMap": true, "declaration": true, "allowSyntheticDefaultImports": true, From 3efae467e739dd79a10af59c081bbe3de2cb1015 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 16 Apr 2022 22:33:11 +0530 Subject: [PATCH 4/4] fix: explicitly ignores non-capture groups --- src/index.ts | 8 +++++--- tests/regex.test.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7878c36..ab56fa6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,9 +24,11 @@ export type RegExCaptureResult = : never : Re extends `(${infer group})?${infer rest}` | `(${infer group})*${infer rest}` ? Partial> & RegExCaptureResult - : Re extends `${infer _}(${infer rest}` - ? RegExCaptureResult<`(${rest}`> - : {}; + : Re extends `${infer _}(?:${infer _})${infer rest}` + ? RegExCaptureResult + : Re extends `${infer _}(${infer rest}` + ? RegExCaptureResult<`(${rest}`> + : {}; export type RegExMatchResult = { matched: boolean; diff --git a/tests/regex.test.ts b/tests/regex.test.ts index 1403e38..0a2692a 100644 --- a/tests/regex.test.ts +++ b/tests/regex.test.ts @@ -146,7 +146,7 @@ describe('TypedRegEx', () => { expect(result).not.toBeNull(); expect(result?.name).toBe('ar'); - // assert_type>(); + assert_type>(); }); }); });