@@ -41,6 +41,9 @@ function cleanParameterTypes(params: string): string {
4141 depth --
4242 }
4343 else if ( char === ',' && depth === 0 ) {
44+ if ( currentParam . trim ( ) . endsWith ( 'as const' ) ) {
45+ currentParam = currentParam . slice ( 0 , currentParam . indexOf ( 'as const' ) ) . trim ( )
46+ }
4447 cleanParams . push ( cleanParameter ( currentParam . trim ( ) ) )
4548 currentParam = ''
4649 continue
@@ -51,6 +54,9 @@ function cleanParameterTypes(params: string): string {
5154 }
5255
5356 if ( currentParam . trim ( ) ) {
57+ if ( currentParam . trim ( ) . endsWith ( 'as const' ) ) {
58+ currentParam = currentParam . slice ( 0 , currentParam . indexOf ( 'as const' ) ) . trim ( )
59+ }
5460 cleanParams . push ( cleanParameter ( currentParam . trim ( ) ) )
5561 }
5662
@@ -612,8 +618,10 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
612618 debugLog ( state , 'infer-array-value' , `Input value:\n${ value } ` )
613619
614620 const content = value . slice ( 1 , - 1 ) . trim ( )
621+ const isConstAssertion = value . trim ( ) . endsWith ( 'as const' )
622+
615623 if ( ! content )
616- return 'unknown[]'
624+ return isConstAssertion ? 'readonly unknown[]' : 'unknown[]'
617625
618626 const baseIndent = ' ' . repeat ( indentLevel )
619627 debugLog ( state , 'infer-array-indent' , `Base indent="${ baseIndent } "` )
@@ -624,11 +632,14 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
624632 const allConstTuples = elements . every ( el => el . trim ( ) . endsWith ( 'as const' ) )
625633 debugLog ( state , 'array-tuples' , `All const tuples: ${ allConstTuples } ` )
626634
627- if ( allConstTuples ) {
635+ // Handle const assertions
636+ if ( isConstAssertion || allConstTuples || content . includes ( 'as const' ) ) {
628637 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 )
632643 } )
633644 debugLog ( state , 'const-tuple' , `Tuples inferred: ${ tuples } ` )
634645
@@ -637,10 +648,10 @@ function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0)
637648 const isLast = i === tuples . length - 1
638649 return indentMultilineType ( type , `${ baseIndent } ` , isLast )
639650 } ) . join ( '\n' )
640- return `Array< \n${ formattedContent } \n${ baseIndent } > `
651+ return `readonly [ \n${ formattedContent } \n${ baseIndent } ] `
641652 }
642653
643- return `Array< ${ tuples . join ( ' | ' ) } > `
654+ return `readonly [ ${ tuples . join ( ', ' ) } ] `
644655 }
645656
646657 const elementTypes = elements . map ( ( element , index ) => {
@@ -720,6 +731,11 @@ function inferComplexObjectType(value: string, state?: ProcessingState, indentLe
720731function inferConstArrayType ( value : string , state ?: ProcessingState ) : string {
721732 debugLog ( state , 'infer-const' , `Inferring const array type for: ${ value } ` )
722733
734+ // For string literals, return them directly
735+ if ( / ^ [ ' " ` ] .* [ ' " ` ] $ / . test ( value ) ) {
736+ return value // Return the literal directly
737+ }
738+
723739 // Handle array literals
724740 if ( value . startsWith ( '[' ) ) {
725741 const content = value . slice ( 1 , - 1 ) . trim ( )
@@ -730,32 +746,44 @@ function inferConstArrayType(value: string, state?: ProcessingState): string {
730746 const trimmed = element . trim ( )
731747 debugLog ( state , 'const-tuple-element' , `Processing tuple element: ${ trimmed } ` )
732748
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+
733755 // Handle nested arrays
734756 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 )
736762 }
737763
738764 // Handle nested objects
739765 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 ' )
741769 }
742770
743- // Preserve string literals
771+ // Handle string literals - ensure they're properly quoted
744772 if ( / ^ [ ' " ` ] .* [ ' " ` ] $ / . test ( trimmed ) ) {
745- return trimmed
773+ return trimmed . replace ( / ^ [ ' " ` ] | [ ' " ` ] $ / g , '\'' ) // Normalize to single quotes
746774 }
747775
748- // Preserve numeric literals
776+ // Handle numeric literals
749777 if ( ! Number . isNaN ( Number ( trimmed ) ) ) {
750778 return trimmed
751779 }
752780
753- // Preserve boolean literals
781+ // Handle boolean literals
754782 if ( trimmed === 'true' || trimmed === 'false' ) {
755783 return trimmed
756784 }
757785
758- return 'unknown'
786+ return trimmed . replace ( / ^ [ ' " ` ] | [ ' " ` ] $ / g , '\'' ) // Normalize any remaining string literals
759787 } )
760788
761789 debugLog ( state , 'const-tuple-result' , `Generated tuple types: [${ literalTypes . join ( ', ' ) } ]` )
@@ -1008,24 +1036,6 @@ export function processBlock(lines: string[], comments: string[], state: Process
10081036 debugLog ( state , 'processing' , `Unhandled declaration type: ${ cleanDeclaration . split ( '\n' ) [ 0 ] } ` )
10091037}
10101038
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-
10291039export function processSpecificDeclaration ( declarationWithoutComments : string , fullDeclaration : string , state : ProcessingState ) : void {
10301040 state . debug . currentProcessing = declarationWithoutComments
10311041 debugLog ( state , 'processing' , `Processing declaration: ${ declarationWithoutComments . substring ( 0 , 100 ) } ...` )
0 commit comments