11// Utils
22// Compensation
33type As < T , _Infer extends T > = unknown ;
4- type Head < T extends unknown [ ] > = T [ 0 ] ;
5- type Tail < T extends unknown [ ] > = T extends [ infer _ , ...infer Rest ]
4+ export type Head < T extends unknown [ ] > = T [ 0 ] ;
5+ /**
6+ * Grab the tail of a list (all elements except the first)
7+ *
8+ * @example
9+ * ```ts
10+ * // Will omit the 0-th capture, leaving only the capture groups
11+ * type Captures = Tail<ParseCaptures<MyRegex>>;
12+ * ```
13+ */
14+ export type Tail < T extends unknown [ ] > = T extends [ infer _ , ...infer Rest ]
615 ? Rest
716 : never
817;
@@ -273,7 +282,7 @@ type IndexTokenInternal<TToken extends Token, TIndex extends number> = TToken ex
273282 left : IndexTokenInternal < TToken [ 'left' ] , TIndex > ,
274283 right : IndexTokenInternal < TToken [ 'right' ] , Add <
275284 TIndex ,
276- FlattenToken < TToken [ 'left' ] > [ 'length' ]
285+ FlattenToken < TToken [ 'left' ] > [ 'length' ]
277286 & number
278287 > >
279288} : TToken extends { type : 'groups' } ? {
@@ -283,7 +292,7 @@ type IndexTokenInternal<TToken extends Token, TIndex extends number> = TToken ex
283292;
284293type IndexToken < TToken extends Token > = IndexTokenInternal < TToken , 0 > ;
285294// TokenWithIndex type
286- type TokenWithIndex = IsSatisfied < { type : string } ,
295+ type TokenWithIndex = IsSatisfied < { type : string } ,
287296{
288297 type : 'alternation' ,
289298 left : TokenWithIndex ,
@@ -374,7 +383,10 @@ type Distribute<T extends Record<
374383 : never
375384;
376385
377- type Parse < T extends string > = string extends T
386+ /**
387+ * Parse the capture groups from a regex-like string literal type
388+ */
389+ export type Parse < T extends string > = string extends T
378390 ? {
379391 captures : [ string , ...( string | undefined ) [ ] ] ,
380392 namedCaptures : Record < string , string | undefined > ;
@@ -391,6 +403,30 @@ type Parse<T extends string> = string extends T
391403 } > > >
392404;
393405
406+ /**
407+ * Get the list of indexed captures from a regex-like string literal type
408+ *
409+ * @example
410+ * ```ts
411+ * // Will get all non-named captures, including the string itself at index 0
412+ * type AllCaptures = ParseCaptures<MyRegex>;
413+ *
414+ * // Will omit the 0-th capture, leaving only the capture groups
415+ * type OnlyGroups = Tail<ParseCaptures<MyRegex>>;
416+ * ```
417+ */
418+ export type ParseCaptures < T extends string > = Parse < T > [ 'captures' ] ;
419+
420+ /**
421+ * Get the dictionary of named captures from a regex-like string literal type
422+ *
423+ * @example
424+ * ```ts
425+ * type AllNamedCaptures = ParseNamedCaptures<MyRegex>;
426+ * ```
427+ */
428+ export type ParseNamedCaptures < T extends string > = Parse < T > [ 'namedCaptures' ] ;
429+
394430type Remove < Ts extends unknown [ ] , TMatch extends Ts [ number ] > = unknown extends AsLinked < Ts , infer First , infer Rest >
395431 ? TMatch extends First
396432 ? Rest
@@ -594,4 +630,5 @@ export const typedRegExp = <
594630 & ( GlobalFalseIndicesBehavior < false > | GlobalFalseIndicesBehavior < true > )
595631 )
596632 ) & ( IndicesBehavior < false > | IndicesBehavior < true > ) > ;
597- } ;
633+
634+ } ;
0 commit comments