diff --git a/src/index.ts b/src/index.ts index 0c59672..ab56fa6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,9 +22,13 @@ 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 _})${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 e787264..0a2692a 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,6 +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@0.1.2'); + expect(result).not.toBeNull(); + expect(result?.version).toBe('0.1.2'); + + assert_type>(); }); }); @@ -64,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>() }); }); @@ -123,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,