@@ -41,6 +41,9 @@ function cleanParameterTypes(params: string): string {
41
41
depth --
42
42
}
43
43
else if ( char === ',' && depth === 0 ) {
44
+ if ( currentParam . trim ( ) . endsWith ( 'as const' ) ) {
45
+ currentParam = currentParam . slice ( 0 , currentParam . indexOf ( 'as const' ) ) . trim ( )
46
+ }
44
47
cleanParams . push ( cleanParameter ( currentParam . trim ( ) ) )
45
48
currentParam = ''
46
49
continue
@@ -51,6 +54,9 @@ function cleanParameterTypes(params: string): string {
51
54
}
52
55
53
56
if ( currentParam . trim ( ) ) {
57
+ if ( currentParam . trim ( ) . endsWith ( 'as const' ) ) {
58
+ currentParam = currentParam . slice ( 0 , currentParam . indexOf ( 'as const' ) ) . trim ( )
59
+ }
54
60
cleanParams . push ( cleanParameter ( currentParam . trim ( ) ) )
55
61
}
56
62
@@ -612,8 +618,10 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
612
618
debugLog ( state , 'infer-array-value' , `Input value:\n${ value } ` )
613
619
614
620
const content = value . slice ( 1 , - 1 ) . trim ( )
621
+ const isConstAssertion = value . trim ( ) . endsWith ( 'as const' )
622
+
615
623
if ( ! content )
616
- return 'unknown[]'
624
+ return isConstAssertion ? 'readonly unknown[]' : 'unknown[]'
617
625
618
626
const baseIndent = ' ' . repeat ( indentLevel )
619
627
debugLog ( state , 'infer-array-indent' , `Base indent="${ baseIndent } "` )
@@ -624,11 +632,14 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
624
632
const allConstTuples = elements . every ( el => el . trim ( ) . endsWith ( 'as const' ) )
625
633
debugLog ( state , 'array-tuples' , `All const tuples: ${ allConstTuples } ` )
626
634
627
- if ( allConstTuples ) {
635
+ // Handle const assertions
636
+ if ( isConstAssertion || allConstTuples || content . includes ( 'as const' ) ) {
628
637
const tuples = elements . map ( ( el ) => {
629
- const tupleContent = el . slice ( 0 , el . indexOf ( 'as const' ) ) . trim ( )
630
- debugLog ( state , 'const-tuple' , `Processing const tuple: ${ tupleContent } ` )
631
- return inferConstArrayType ( tupleContent , state )
638
+ const cleaned = el . trim ( ) . endsWith ( 'as const' )
639
+ ? el . slice ( 0 , el . indexOf ( 'as const' ) ) . trim ( )
640
+ : el . trim ( )
641
+ debugLog ( state , 'const-tuple' , `Processing const tuple: ${ cleaned } ` )
642
+ return inferConstArrayType ( cleaned , state )
632
643
} )
633
644
debugLog ( state , 'const-tuple' , `Tuples inferred: ${ tuples } ` )
634
645
@@ -637,10 +648,10 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
637
648
const isLast = i === tuples . length - 1
638
649
return indentMultilineType ( type , `${ baseIndent } ` , isLast )
639
650
} ) . join ( '\n' )
640
- return `Array< \n${ formattedContent } \n${ baseIndent } > `
651
+ return `readonly [ \n${ formattedContent } \n${ baseIndent } ] `
641
652
}
642
653
643
- return `Array< ${ tuples . join ( ' | ' ) } > `
654
+ return `readonly [ ${ tuples . join ( ', ' ) } ] `
644
655
}
645
656
646
657
const elementTypes = elements . map ( ( element , index ) => {
@@ -720,6 +731,11 @@ function inferComplexObjectType(value: string, state?: ProcessingState, indentLe
720
731
function inferConstArrayType ( value : string , state ?: ProcessingState ) : string {
721
732
debugLog ( state , 'infer-const' , `Inferring const array type for: ${ value } ` )
722
733
734
+ // For string literals, return them directly
735
+ if ( / ^ [ ' " ` ] .* [ ' " ` ] $ / . test ( value ) ) {
736
+ return value // Return the literal directly
737
+ }
738
+
723
739
// Handle array literals
724
740
if ( value . startsWith ( '[' ) ) {
725
741
const content = value . slice ( 1 , - 1 ) . trim ( )
@@ -730,32 +746,44 @@ function inferConstArrayType(value: string, state?: ProcessingState): string {
730
746
const trimmed = element . trim ( )
731
747
debugLog ( state , 'const-tuple-element' , `Processing tuple element: ${ trimmed } ` )
732
748
749
+ // Remove '] as cons' artifact if present
750
+ if ( trimmed . includes ( '] as cons' ) ) {
751
+ const cleanTrimmed = trimmed . replace ( '] as cons' , '' ) . trim ( )
752
+ return cleanTrimmed . replace ( / ^ [ ' " ` ] | [ ' " ` ] $ / g, '\'' )
753
+ }
754
+
733
755
// Handle nested arrays
734
756
if ( trimmed . startsWith ( '[' ) ) {
735
- return inferConstArrayType ( trimmed , state )
757
+ // Remove any 'as const' from nested arrays
758
+ const cleanTrimmed = trimmed . endsWith ( 'as const' )
759
+ ? trimmed . slice ( 0 , trimmed . indexOf ( 'as const' ) ) . trim ( )
760
+ : trimmed
761
+ return inferConstArrayType ( cleanTrimmed , state )
736
762
}
737
763
738
764
// Handle nested objects
739
765
if ( trimmed . startsWith ( '{' ) ) {
740
- return inferComplexObjectType ( trimmed , state )
766
+ const result = inferComplexObjectType ( trimmed , state )
767
+ // Make object properties readonly for const assertions
768
+ return result . replace ( / ^ \{ / , '{ readonly' ) . replace ( / ; \s + / g, '; readonly ' )
741
769
}
742
770
743
- // Preserve string literals
771
+ // Handle string literals - ensure they're properly quoted
744
772
if ( / ^ [ ' " ` ] .* [ ' " ` ] $ / . test ( trimmed ) ) {
745
- return trimmed
773
+ return trimmed . replace ( / ^ [ ' " ` ] | [ ' " ` ] $ / g , '\'' ) // Normalize to single quotes
746
774
}
747
775
748
- // Preserve numeric literals
776
+ // Handle numeric literals
749
777
if ( ! Number . isNaN ( Number ( trimmed ) ) ) {
750
778
return trimmed
751
779
}
752
780
753
- // Preserve boolean literals
781
+ // Handle boolean literals
754
782
if ( trimmed === 'true' || trimmed === 'false' ) {
755
783
return trimmed
756
784
}
757
785
758
- return 'unknown'
786
+ return trimmed . replace ( / ^ [ ' " ` ] | [ ' " ` ] $ / g , '\'' ) // Normalize any remaining string literals
759
787
} )
760
788
761
789
debugLog ( state , 'const-tuple-result' , `Generated tuple types: [${ literalTypes . join ( ', ' ) } ]` )
@@ -1008,24 +1036,6 @@ export function processBlock(lines: string[], comments: string[], state: Process
1008
1036
debugLog ( state , 'processing' , `Unhandled declaration type: ${ cleanDeclaration . split ( '\n' ) [ 0 ] } ` )
1009
1037
}
1010
1038
1011
- function processDeclaration ( declaration : string ) : boolean {
1012
- let bracketDepth = 0
1013
- let parenDepth = 0
1014
-
1015
- for ( const char of declaration ) {
1016
- if ( char === '(' )
1017
- parenDepth ++
1018
- if ( char === ')' )
1019
- parenDepth --
1020
- if ( char === '{' )
1021
- bracketDepth ++
1022
- if ( char === '}' )
1023
- bracketDepth --
1024
- }
1025
-
1026
- return bracketDepth === 0 && parenDepth === 0
1027
- }
1028
-
1029
1039
export function processSpecificDeclaration ( declarationWithoutComments : string , fullDeclaration : string , state : ProcessingState ) : void {
1030
1040
state . debug . currentProcessing = declarationWithoutComments
1031
1041
debugLog ( state , 'processing' , `Processing declaration: ${ declarationWithoutComments . substring ( 0 , 100 ) } ...` )
0 commit comments