@@ -50,7 +50,7 @@ type IsSatisfied<T, TMember extends T> = TMember;
5050type Is < T extends boolean , TIf , TElse > = T extends true
5151 ? TIf
5252 : TElse
53- ; // Works with T of `boolean`;
53+ ; // Works with T of `boolean`
5454type CharOfInternal < T extends string > = T extends `${infer First } ${infer Rest } `
5555 ? First | CharOfInternal < Rest >
5656 : never
@@ -235,7 +235,7 @@ type Token = IsSatisfied<{ type: string },
235235} > ;
236236type Groups = ( Token & { type : 'groups' } ) [ 'groups' ] ;
237237// Indexification (DFS)
238- // Utils (DFS math)
238+ // Utils
239239type FlattenGroupsDeep < TGroups extends Groups > = unknown extends AsLinked < TGroups , infer First , infer Rest >
240240 ? [ First , ...FlattenTokenDeep < First [ 'inner' ] > , ...FlattenGroupsDeep <
241241 // @ts -expect-error: TS cannot infer that this extends 'Groups'
@@ -472,7 +472,7 @@ export const typedRegExp = <
472472 > & Omit < Captures , number extends Captures [ 'length' ]
473473 ? never
474474 : number
475- > & ( RegExpExecArray extends { indices : infer Indices } // Potentially breaks something niche?
475+ > & ( RegExpExecArray extends { indices : infer Indices }
476476 ? Is < HasFlag < 'd' > ,
477477 { indices : NonNullable < Indices > } ,
478478 { }
@@ -518,8 +518,7 @@ export const typedRegExp = <
518518 } ,
519519 { }
520520 ) ;
521- // for some reason GlobalMatches hits recursion limit faster?
522- type GlobalMatches = [ Head < Captures > , ...Head < Captures > [ ] ] ; // can't be empty arr. Either null or one+.
521+ type GlobalMatches = [ Head < Captures > , ...Head < Captures > [ ] ] ;
523522 const ret = {
524523 regExp,
525524 ...toPOJO ( regExp as Override < typeof regExp , {
@@ -529,17 +528,14 @@ export const typedRegExp = <
529528 global : HasFlag < 'g' > ,
530529 hasIndices : HasFlag < 'd' > ,
531530 ignoreCase : HasFlag < 'i' > ,
532- // lastIndex: number, // the only mutable prop. Can be set manually or under the hood through 'g' and 'y' flag.
533531 multiLine : HasFlag < 'm' > ,
534532 source : TPattern extends ''
535533 ? '(?:)'
536534 : TPattern
537535 ,
538536 sticky : HasFlag < 'y' > ,
539- // test: () => ,
540537 unicode : HasFlag < 'u' > ,
541538 unicodeSets : HasFlag < 'v' > ,
542- // compile: () => ,
543539 } > ) ,
544540 matchIn : < T extends string > (
545541 source : T
@@ -552,13 +548,13 @@ export const typedRegExp = <
552548 splitIn : ( source : string , ...args : Tail < Parameters < string [ 'split' ] > > ) => source . split ( regExp , ...args ) ,
553549 ...ternaryGlobalMethods ( isGlobal )
554550 } ;
555- // ternaryGlobalMethods + code below specifically to help TS for discriminated unions (global + hasIndices). Potentially remove as it's unscalable and weird .
551+ // code below specifically to help TS for discriminated unions (global + hasIndices).
556552 type StrictRegExpExecArrayForHasIndices < T extends boolean , TString extends string > = StrictRegExpExecArray < TString > & Is < T , { indices : NonNullable < RegExpExecArray [ 'indices' ] > } , { } > ;
557553 type GlobalBehavior < T extends boolean > = {
558554 global : T
559555 } & ReturnType < typeof ternaryGlobalMethods < T > > ;
560556 type HasIndicesOnExistence < T extends boolean > = 'hasIndices' extends keyof RegExp
561- ? { hasIndices : T }
557+ ? { hasIndices : T }
562558 : { }
563559 ;
564560 type GlobalTrueIndicesBehavior < T extends boolean > = HasIndicesOnExistence < T > & {
@@ -580,114 +576,4 @@ export const typedRegExp = <
580576 & ( GlobalFalseIndicesBehavior < false > | GlobalFalseIndicesBehavior < true > )
581577 )
582578 ) & ( IndicesBehavior < false > | IndicesBehavior < true > ) > ;
583- } ;
584-
585- typedRegExp ( '?<named>' ) . matchIn ( '(?<named>)' ) ! . groups ; // HANDLE!
586-
587- // #region Runtime tests
588-
589- // #region Version tests
590-
591- // // < es2018
592- const normalGroups = new RegExp ( '' ) . exec ( '' ) ! . groups ;
593- const typedGroups = typedRegExp ( '' ) . exec ( '' ) ! . groups ;
594- // // < es2022
595- const normalHasIndices = new RegExp ( '' ) . hasIndices ;
596- const typedHasIndices = typedRegExp ( '' ) . hasIndices ;
597- const normalIndices = new RegExp ( '' ) . exec ( '' ) ! . indices ;
598- const typedIndices = typedRegExp ( '' , 'd' ) . exec ( '' ) ! . indices ;
599-
600- // #endregion
601-
602- // #region General tests
603-
604- const check = typedRegExp ( '' ) [ Symbol . match ] ( '' ) ; // Error!
605-
606- const conditionFlagsSuccess = typedRegExp ( '(?<hello>)(?<world>)' , 'd' ) . exec ( '' ) ! . indices ;
607- const conditionFlagsFail = typedRegExp ( '(?<hello>)(?<world>)' , '' ) . exec ( '' ) ! . indices ; // Error!
608-
609- const gettingFlags = typedRegExp ( 'lolxd' , 'gid' ) . flags ; // 'dgi'
610- const gettingFlagsNonLiteral = typedRegExp ( 'lolxd' , 'gid' as string ) . flags ; // string
611- const gettingSource = typedRegExp ( 'lolxd' , 'gid' ) . source ; // 'lolxd'
612- const gettingSourceEmpty = typedRegExp ( '' , 'gid' ) . source ; // '(?:)'
613- const getTypedRegExpNonLiteralSource = < const TFlags extends string > ( flags : ValidatedFlags < TFlags > ) => typedRegExp ( '(?<namedGroup>))' as string , flags ) ;
614- const typedRegExpNonLiteralSourceGlobalFlags = getTypedRegExpNonLiteralSource ( 'gid' ) ;
615- const gettingSourceNonLiteral0 = typedRegExpNonLiteralSourceGlobalFlags . exec ( '' ) ! [ 0 ] ; // string
616- const gettingSourceNonLiteralIndex = typedRegExpNonLiteralSourceGlobalFlags . exec ( '' ) ! [ 34 ] ; // string | undefined
617- const gettingSourceNonLiteral = typedRegExpNonLiteralSourceGlobalFlags . exec ( '' ) ! . groups ; // RegExp['groups']
618- const gettingSourceNonLiteralMatchGlobal = typedRegExpNonLiteralSourceGlobalFlags . matchIn ( '' ) ; // [string, ...string[]] | null
619- const gettingSourceNonLiteralMatchIndices = getTypedRegExpNonLiteralSource ( 'id' ) . matchIn ( '' ) ; // StrictRegExpExecArrayForHasIndices<true> | null
620- const gettingSourceNonLiteralMatch = getTypedRegExpNonLiteralSource ( 'i' ) . matchIn ( '' ) ; // StrictRegExpExecArrayForHasIndices<false> | null
621- const gettingSourceNonLiteralReplace = typedRegExpNonLiteralSourceGlobalFlags . replaceIn ( 'source' , ( ...args ) => {
622- const match = args [ 0 ] ; // string
623- const rest = args [ 1 ] ; // string | number | Record<string, string | undefined> | undefined
624- return '' ;
625- } ) ;
626- const matched1 = typedRegExp ( '(?<hello>)(?<world>)' , 'dg' ) . matchIn ( '' ) ! [ 0 ] ; // string
627- const matched2 = typedRegExp ( '(?<hello>)(?<world>)' , 'dg' ) . matchIn ( '' ) ! [ 1 ] ; // string | undefined
628- const replacedThroughValue = typedRegExp ( '((?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}))?' , '' ) . replaceIn ( '' , 'replacement-value' ) ;
629- const replaceThroughReplacer = typedRegExp ( '(?<main>..(?<nested>.))?' , '' ) . replaceIn ( '' , ( match , main , nested , offset , string , groups ) => groups . nested ! ) ;
630- const replaceThroughReplacerNotAllArgs = typedRegExp ( '(?<main>..(?<nested>.))?' , '' ) . replaceIn ( '' , ( match , main , nested , offset , string , ...rest ) => nested ! ) ; // todo (probably nothing that can be done): rest as destructured tuple instead of full Array?
631-
632- const interesting = typedRegExp ( '(?<a>...)|(?<b>...(?<bInner>))?|(?<c>...)' ) . exec ( 'dffdf' ) ! ;
633- const interestingOut = interesting . groups . a ;
634- if ( interesting . groups . bInner === undefined && interesting . groups . c === undefined ) {
635- const interstingIn = interesting . groups . a ; // string | undefined
636- }
637-
638- const myTest = typedRegExp ( '(?<main>.(?<nested>.))?' ) . exec ( '' ) ! . groups ;
639- const main = myTest . main ; // string | undefined
640- if ( myTest . nested === undefined ) {
641- const inner = myTest . main ; // undefined
642- }
643-
644- const c = typedRegExp ( '(?<main>(?<nested>))?' , 'g' as string ) ;
645- for ( const match of 'matchAllIn' in c ? c . matchAllIn ( '' ) : [ ] ) {
646- type Out = typeof match . groups . nested ;
647- if ( match . groups . main ) {
648- type In = typeof match . groups . nested ;
649- const haa = match . indices ; // should error
650- const lastGroup = match [ 3 ] ; // should error
651- }
652- `Found ${ match [ 0 ] } start=${ match . index } end=${ match . index + match [ 0 ] . length } .` ;
653- }
654-
655- // #endregion
656-
657- // #region Non-literal tests
658-
659- const nonLiteralFlags = typedRegExp ( '(?<hello>)(?<world>)' , 'dg' as string ) ;
660- if ( nonLiteralFlags . hasIndices ) {
661- const inds = nonLiteralFlags . exec ( '' ) ! . indices ; // RegExpIndicesArray
662- const inds2 = nonLiteralFlags . matchIn ( '' ) ! . indices ; // Error!
663- if ( ! nonLiteralFlags . global ) {
664- const inds2_2 = nonLiteralFlags . matchIn ( '' ) ! . indices ; // RegExpIndicesArray
665- } else {
666- for ( const l of nonLiteralFlags . matchAllIn ( '' ) ) {
667- l . indices ; // RegExpIndicesArray
668- }
669- }
670- }
671- const mtch = nonLiteralFlags . matchIn ( '' ) ; // StrictRegExpExecArray | [string, ...string[]] | null
672- if ( nonLiteralFlags . global ) {
673- const inmtch = nonLiteralFlags . matchIn ( '' ) ; // [string, ...string[]] | null
674- for ( const inmtch2 of nonLiteralFlags . matchAllIn ( '' ) ) {
675- inmtch2 . indices ; // Error!
676- if ( 'indices' in inmtch2 ) {
677- const indices = inmtch2 . indices ; // RegExpIndicesArray
678- }
679- }
680- const rplcAll = nonLiteralFlags . replaceAllIn ( '' , '' ) ;
681- } else {
682- const inmtch = nonLiteralFlags . matchIn ( '' ) ! ; // StrictRegExpExecArray | null
683- inmtch . indices ; // Error!
684- if ( 'indices' in inmtch ) {
685- const indices = inmtch . indices ; // RegExpIndicesArray
686- }
687- }
688-
689- // #endregion
690-
691- // #endregion
692-
693- // #endregion
579+ } ;
0 commit comments