@@ -784,7 +784,7 @@ export function processTypeDeclaration(declaration: string, isExported = true):
784784}
785785
786786/**
787- * Enhanced function signature extraction with better destructuring and generics support
787+ * Extract complete function signature
788788 */
789789export interface FunctionSignature {
790790 name : string
@@ -814,9 +814,11 @@ export function extractFunctionSignature(declaration: string): FunctionSignature
814814 . replace ( / ^ f u n c t i o n \s + / , '' )
815815 . trim ( )
816816
817- // Extract generics with improved regex
817+ // Extract complete generic section including constraints
818818 const genericsMatch = cleanDeclaration . match ( / < ( [ ^ > ] + ) > (? = \s * \( ) / )
819- const generics = genericsMatch ? `<${ genericsMatch [ 1 ] } >` : ''
819+ const generics = genericsMatch
820+ ? normalizeGenerics ( genericsMatch [ 1 ] )
821+ : ''
820822
821823 // Remove generics for further parsing
822824 const withoutGenerics = cleanDeclaration . replace ( / < ( [ ^ > ] + ) > (? = \s * \( ) / , '' )
@@ -829,25 +831,42 @@ export function extractFunctionSignature(declaration: string): FunctionSignature
829831 const paramsMatch = withoutGenerics . match ( / \( ( [ \s \S ] * ?) \) (? = \s * : ) / )
830832 let params = paramsMatch ? paramsMatch [ 1 ] . trim ( ) : ''
831833
832- // Clean up parameters
834+ // Clean up parameters while preserving generic references
833835 params = cleanParameters ( params )
834836
835- // Extract return type with improved generic handling
837+ // Extract return type with generic preservation
836838 const returnTypeMatch = withoutGenerics . match ( / \) \s * : \s * ( [ \s \S ] + ?) (? = \{ | $ ) / )
837839 let returnType = returnTypeMatch ? returnTypeMatch [ 1 ] . trim ( ) : 'void'
838840
839841 // Ensure generic type parameters in return types are preserved
840- returnType = returnType . replace ( / \s + / g , '' )
842+ returnType = normalizeType ( returnType )
841843
842844 return {
843845 name,
844846 params,
845847 returnType,
846848 isAsync : declaration . includes ( 'async' ) ,
847- generics,
849+ generics : generics ? `< ${ generics } >` : '' ,
848850 }
849851}
850852
853+ /**
854+ * Normalize generic type parameters and constraints
855+ */
856+ function normalizeGenerics ( generics : string ) : string {
857+ return generics
858+ . split ( ',' )
859+ . map ( ( param ) => {
860+ const parts = param . trim ( ) . split ( / \s + e x t e n d s \s + / )
861+ if ( parts . length === 2 ) {
862+ const [ typeParam , constraint ] = parts
863+ return `${ typeParam . trim ( ) } extends ${ normalizeType ( constraint ) } `
864+ }
865+ return param . trim ( )
866+ } )
867+ . join ( ', ' )
868+ }
869+
851870/**
852871 * Process function declaration with fixed generic handling
853872 */
@@ -864,19 +883,20 @@ export function processFunctionDeclaration(
864883 generics,
865884 } = extractFunctionSignature ( declaration )
866885
867- // Track all used types
886+ // Track all used types including generics
868887 trackUsedTypes ( `${ generics } ${ params } ${ returnType } ` , usedTypes )
869888
870- // Build declaration string ensuring correct placement of generics
889+ // Build declaration string ensuring proper generic scope
871890 const parts = [
872891 isExported ? 'export' : '' ,
873892 'declare' ,
874893 isAsync ? 'async' : '' ,
875894 'function' ,
876895 name ,
896+ // Ensure generics are properly placed
877897 generics ,
878898 `(${ params } )` ,
879- `:` ,
899+ ':' ,
880900 returnType ,
881901 ';' ,
882902 ]
@@ -886,7 +906,7 @@ export function processFunctionDeclaration(
886906 . join ( ' ' )
887907 . replace ( / \s + ( [ < > ( ) , ; : ] ) / g, '$1' )
888908 . replace ( / ( [ < > ( ) , ; : ] ) \s + / g, '$1 ' )
889- . replace ( / \s + / g, ' ' )
909+ . replace ( / \s { 2 , } / g, ' ' )
890910 . trim ( )
891911}
892912
@@ -898,27 +918,36 @@ export function cleanParameters(params: string): string {
898918 return ''
899919
900920 return params
901- // Handle destructured parameters
921+ // Handle destructured parameters while preserving generic references
902922 . replace ( / \{ ( [ ^ } ] + ) \} : \s * ( [ ^ , ) ] + ) / g, ( _ , props , type ) => {
903- // Convert destructured parameters to a single options parameter
904- const typeName = type . trim ( )
923+ // Preserve the generic type reference
924+ const typeName = normalizeType ( type . trim ( ) )
905925 return `options: ${ typeName } `
906926 } )
907927 // Normalize spaces around special characters
908928 . replace ( / \s * ( [ , : ] ) \s * / g, '$1 ' )
909- // Clean up multiple spaces
910- . replace ( / \s + / g, ' ' )
911929 // Add space after commas if missing
912930 . replace ( / , ( \S ) / g, ', $1' )
913931 // Normalize optional parameter syntax
914932 . replace ( / \s * \? \s * : / g, '?: ' )
915- // Clean up spaces around array/generic brackets
933+ // Clean up spaces around array/generic brackets while preserving content
916934 . replace ( / \s * ( [ < [ \] > ] ) \s * / g, '$1' )
917935 // Final cleanup of any double spaces
918936 . replace ( / \s { 2 , } / g, ' ' )
919937 . trim ( )
920938}
921939
940+ /**
941+ * Normalize type references while preserving generic parameters
942+ */
943+ function normalizeType ( type : string ) : string {
944+ return type
945+ . replace ( / \s + / g, ' ' )
946+ . replace ( / \s * ( [ < > ] ) \s * / g, '$1' )
947+ . replace ( / \s * , \s * / g, ', ' )
948+ . trim ( )
949+ }
950+
922951/**
923952 * Track used types in function signatures and bodies
924953 */
@@ -932,7 +961,7 @@ export function trackUsedTypes(content: string, usedTypes: Set<string>): void {
932961 if ( type ) {
933962 // Extract base type and any nested generic types
934963 const [ baseType , ...genericParams ] = type . split ( / [ < > ] / )
935- if ( baseType )
964+ if ( baseType && / ^ [ A - Z ] / . test ( baseType ) )
936965 usedTypes . add ( baseType )
937966
938967 // Process generic parameters
0 commit comments