-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
magic-regexp.ts
40 lines (34 loc) · 1.33 KB
/
magic-regexp.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const NamedGroupsS = Symbol('NamedGroups')
const ValueS = Symbol('Value')
const CapturedGroupsArrS = Symbol('CapturedGroupsArr')
const FlagsS = Symbol('Flags')
export type MagicRegExp<
Value extends string,
NamedGroups extends string | never = never,
CapturedGroupsArr extends (string | undefined)[] = [],
Flags extends string | never = never
> = RegExp & {
[NamedGroupsS]: NamedGroups
[CapturedGroupsArrS]: CapturedGroupsArr
[ValueS]: Value
[FlagsS]: Flags
}
type ExtractGroups<T extends MagicRegExp<string, string, (string | undefined)[], string>> =
T extends MagicRegExp<string, infer V, (string | undefined)[], string> ? V : never
type StringWithHint<S extends string> = string & {
_capturedBy: S
}
export type StringCapturedBy<S extends string> = StringWithHint<S>
export type MapToStringCapturedBy<Ar extends (string | undefined)[]> = {
[K in keyof Ar]: Ar[K] extends string ? StringCapturedBy<Ar[K]> | undefined : undefined
}
export type MagicRegExpMatchArray<T extends MagicRegExp<string, string, any[], string>> = Omit<
RegExpMatchArray,
'groups'
> & {
groups: Record<ExtractGroups<T>, string | undefined>
} & {
[index: number | string | symbol]: never
} & (T extends MagicRegExp<string, string, infer CapturedGroupsArr, string>
? readonly [string | undefined, ...MapToStringCapturedBy<CapturedGroupsArr>]
: {})