@@ -368,7 +368,7 @@ export function isFunction(value: string): boolean {
368
368
/**
369
369
* Infer array type from array literal
370
370
*/
371
- function inferArrayType ( value : string ) : string {
371
+ export function inferArrayType ( value : string ) : string {
372
372
const content = extractNestedContent ( value , '[' , ']' )
373
373
if ( ! content )
374
374
return 'never[]'
@@ -377,9 +377,27 @@ function inferArrayType(value: string): string {
377
377
if ( elements . length === 0 )
378
378
return 'never[]'
379
379
380
- // Use processNestedArray to handle the array structure
381
- const processedType = processNestedArray ( elements )
382
- return `Array<${ processedType } >`
380
+ // For deeply nested arrays, handle each level properly
381
+ const isNestedArray = elements . some ( el => el . trim ( ) . startsWith ( '[' ) )
382
+ if ( isNestedArray ) {
383
+ const processedTypes = elements . map ( ( element ) => {
384
+ const trimmed = element . trim ( )
385
+ if ( trimmed . startsWith ( '[' ) ) {
386
+ const innerTypes = inferArrayType ( trimmed )
387
+ return innerTypes
388
+ }
389
+ return inferElementType ( trimmed )
390
+ } )
391
+
392
+ // Filter out any invalid types and create union
393
+ const validTypes = processedTypes . filter ( type => type !== 'never' && type !== '' )
394
+ return `Array<${ [ ...new Set ( validTypes ) ] . join ( ' | ' ) } >`
395
+ }
396
+
397
+ // For simple arrays, process elements normally
398
+ const elementTypes = elements . map ( element => inferElementType ( element . trim ( ) ) )
399
+ const uniqueTypes = [ ...new Set ( elementTypes ) ]
400
+ return `Array<${ uniqueTypes . join ( ' | ' ) } >`
383
401
}
384
402
385
403
/**
@@ -404,27 +422,21 @@ export function inferElementType(element: string): string {
404
422
return formatObjectType ( parseObjectLiteral ( trimmed ) )
405
423
}
406
424
407
- // Handle known function references
408
- if ( trimmed === 'console.log' || trimmed . endsWith ( '.log' ) ) {
425
+ // Handle function expressions and references
426
+ if (
427
+ trimmed === 'console.log'
428
+ || trimmed . endsWith ( '.log' )
429
+ || trimmed . includes ( '=>' )
430
+ || trimmed . includes ( 'function' )
431
+ ) {
409
432
return '(...args: any[]) => void'
410
433
}
411
434
412
- // Handle arrow functions
413
- if ( trimmed . includes ( '=>' ) ) {
414
- return '(...args: any[]) => void'
415
- }
416
-
417
- // Handle function calls
418
- if ( trimmed . includes ( '(' ) && trimmed . includes ( ')' ) ) {
419
- return 'unknown'
420
- }
421
-
422
- // Handle references to global objects
423
- if ( trimmed . includes ( '.' ) ) {
435
+ // Handle global references and unknown identifiers
436
+ if ( trimmed . includes ( '.' ) || / ^ [ a - z _ ] \w * $ / i. test ( trimmed ) ) {
424
437
return 'unknown'
425
438
}
426
439
427
- // Default case
428
440
return 'unknown'
429
441
}
430
442
@@ -440,16 +452,17 @@ export function processNestedArray(elements: string[]): string {
440
452
const nestedContent = extractNestedContent ( trimmed , '[' , ']' )
441
453
if ( nestedContent ) {
442
454
const nestedElements = splitArrayElements ( nestedContent )
443
- return `Array<${ processNestedArray ( nestedElements ) } >`
455
+ // Ensure nested arrays are properly typed
456
+ const nestedTypes = nestedElements . map ( e => inferElementType ( e . trim ( ) ) )
457
+ return `Array<${ [ ...new Set ( nestedTypes ) ] . join ( ' | ' ) } >`
444
458
}
445
459
return 'never'
446
460
}
447
461
448
462
return inferElementType ( trimmed )
449
- } )
463
+ } ) . filter ( type => type !== 'never' && type !== '' )
450
464
451
- const uniqueTypes = [ ...new Set ( processedTypes . filter ( type => type !== 'never' ) ) ]
452
- return uniqueTypes . join ( ' | ' )
465
+ return [ ...new Set ( processedTypes ) ] . join ( ' | ' )
453
466
}
454
467
455
468
/**
@@ -498,6 +511,7 @@ export function splitArrayElements(content: string): string[] {
498
511
let stringChar = ''
499
512
500
513
for ( const char of content ) {
514
+ // Handle string boundaries
501
515
if ( ( char === '"' || char === '\'' ) && ! inString ) {
502
516
inString = true
503
517
stringChar = char
@@ -506,22 +520,26 @@ export function splitArrayElements(content: string): string[] {
506
520
inString = false
507
521
}
508
522
523
+ // Track nesting depth
509
524
if ( ! inString ) {
510
525
if ( char === '[' || char === '{' )
511
526
depth ++
512
527
else if ( char === ']' || char === '}' )
513
528
depth --
514
529
}
515
530
531
+ // Split elements only at top level
516
532
if ( char === ',' && depth === 0 && ! inString ) {
517
- elements . push ( current . trim ( ) )
533
+ if ( current . trim ( ) )
534
+ elements . push ( current . trim ( ) )
518
535
current = ''
519
536
}
520
537
else {
521
538
current += char
522
539
}
523
540
}
524
541
542
+ // Add the last element
525
543
if ( current . trim ( ) )
526
544
elements . push ( current . trim ( ) )
527
545
0 commit comments