Skip to content

Commit e73671d

Browse files
committed
chore: wip
chore: wip
1 parent e06753d commit e73671d

File tree

2 files changed

+55
-38
lines changed

2 files changed

+55
-38
lines changed

fixtures/output/example-0001.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ export declare const someObject: {
1515
someArray: Array<1 | 2 | 3>;
1616
someNestedArray: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10>>;
1717
someNestedArray2: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value'>;
18-
someNestedArray3: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value', [11, 12, 13]'>;
19-
someOtherNestedArray: Array<Array<'some text', 2, console.log, () => console.log('hello world'), helloWorld'>>;
20-
someComplexArray: Array<Array<Object>>;
18+
someNestedArray3: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value' | Array<11 | 12 | 13>>;
19+
someOtherNestedArray: Array<Array<'some text' | 2 | (...args: any[]) => void | (...args: any[]) => void | unknown> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10>>;
20+
someComplexArray: Array<Array<{ key: 'value' }> | Array<{ key2: 'value2' } | 'test' | 1000> | Array<'some string' | (...args: any[]) => void | unknown>>;
2121
someObject: {
2222
key: 'value';
2323
};
@@ -29,7 +29,7 @@ export declare const someObject: {
2929
nestedKey: (...args: any[]) => void;
3030
};
3131
};
32-
someNestedObjectArray: Array<Object>;
32+
someNestedObjectArray: Array<{ key: 'value' } | { key2: 'value2' }>;
3333
someOtherObject: unknown;
3434
someInlineCall2: (...args: any[]) => void;
3535
someInlineCall3: (...args: any[]) => void;

src/extract.ts

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -377,24 +377,24 @@ export function inferArrayType(value: string): string {
377377
if (elements.length === 0)
378378
return 'never[]'
379379

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) => {
380+
// Handle case where elements themselves are arrays
381+
if (elements.some(el => el.trim().startsWith('['))) {
382+
const nestedTypes = elements.map((element) => {
384383
const trimmed = element.trim()
385384
if (trimmed.startsWith('[')) {
386-
const innerTypes = inferArrayType(trimmed)
387-
return innerTypes
385+
const nestedContent = extractNestedContent(trimmed, '[', ']')
386+
if (nestedContent) {
387+
const nestedElements = splitArrayElements(nestedContent)
388+
return `Array<${nestedElements.map(ne => inferElementType(ne.trim())).join(' | ')}>`
389+
}
388390
}
389391
return inferElementType(trimmed)
390392
})
391393

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(' | ')}>`
394+
return `Array<${nestedTypes.join(' | ')}>`
395395
}
396396

397-
// For simple arrays, process elements normally
397+
// Handle simple array case
398398
const elementTypes = elements.map(element => inferElementType(element.trim()))
399399
const uniqueTypes = [...new Set(elementTypes)]
400400
return `Array<${uniqueTypes.join(' | ')}>`
@@ -422,18 +422,29 @@ export function inferElementType(element: string): string {
422422
return formatObjectType(parseObjectLiteral(trimmed))
423423
}
424424

425-
// Handle function expressions and references
426-
if (
427-
trimmed === 'console.log'
428-
|| trimmed.endsWith('.log')
429-
|| trimmed.includes('=>')
430-
|| trimmed.includes('function')
431-
) {
425+
// Handle function references and calls
426+
if (trimmed === 'console.log' || trimmed.endsWith('.log')) {
432427
return '(...args: any[]) => void'
433428
}
434429

435-
// Handle global references and unknown identifiers
436-
if (trimmed.includes('.') || /^[a-z_]\w*$/i.test(trimmed)) {
430+
// Handle arrow functions
431+
if (trimmed.includes('=>')) {
432+
const arrowFn = trimmed.match(/\(.*\)\s*=>\s*(.*)/)
433+
return '(...args: any[]) => void'
434+
}
435+
436+
// Handle function calls
437+
if (trimmed.endsWith('()')) {
438+
return 'unknown'
439+
}
440+
441+
// Handle object references
442+
if (trimmed.includes('.')) {
443+
return 'unknown'
444+
}
445+
446+
// Handle identifiers that might be undefined
447+
if (/^[a-z_]\w*$/i.test(trimmed)) {
437448
return 'unknown'
438449
}
439450

@@ -452,17 +463,17 @@ export function processNestedArray(elements: string[]): string {
452463
const nestedContent = extractNestedContent(trimmed, '[', ']')
453464
if (nestedContent) {
454465
const nestedElements = splitArrayElements(nestedContent)
455-
// Ensure nested arrays are properly typed
456-
const nestedTypes = nestedElements.map(e => inferElementType(e.trim()))
457-
return `Array<${[...new Set(nestedTypes)].join(' | ')}>`
466+
// Process each nested element to create a proper union type
467+
const nestedTypes = nestedElements.map(ne => inferElementType(ne.trim()))
468+
return `Array<${nestedTypes.join(' | ')}>`
458469
}
459470
return 'never'
460471
}
461472

462473
return inferElementType(trimmed)
463-
}).filter(type => type !== 'never' && type !== '')
474+
}).filter(type => type !== 'never')
464475

465-
return [...new Set(processedTypes)].join(' | ')
476+
return processedTypes.join(' | ')
466477
}
467478

468479
/**
@@ -510,17 +521,21 @@ export function splitArrayElements(content: string): string[] {
510521
let inString = false
511522
let stringChar = ''
512523

513-
for (const char of content) {
524+
for (let i = 0; i < content.length; i++) {
525+
const char = content[i]
526+
514527
// Handle string boundaries
515-
if ((char === '"' || char === '\'') && !inString) {
516-
inString = true
517-
stringChar = char
518-
}
519-
else if (char === stringChar && !inString) {
520-
inString = false
528+
if ((char === '"' || char === '\'') && (i === 0 || content[i - 1] !== '\\')) {
529+
if (!inString) {
530+
inString = true
531+
stringChar = char
532+
}
533+
else if (char === stringChar) {
534+
inString = false
535+
}
521536
}
522537

523-
// Track nesting depth
538+
// Track nested structures
524539
if (!inString) {
525540
if (char === '[' || char === '{')
526541
depth++
@@ -530,8 +545,9 @@ export function splitArrayElements(content: string): string[] {
530545

531546
// Split elements only at top level
532547
if (char === ',' && depth === 0 && !inString) {
533-
if (current.trim())
548+
if (current.trim()) {
534549
elements.push(current.trim())
550+
}
535551
current = ''
536552
}
537553
else {
@@ -540,8 +556,9 @@ export function splitArrayElements(content: string): string[] {
540556
}
541557

542558
// Add the last element
543-
if (current.trim())
559+
if (current.trim()) {
544560
elements.push(current.trim())
561+
}
545562

546563
return elements.filter(Boolean)
547564
}

0 commit comments

Comments
 (0)