Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
chore: wip
  • Loading branch information
chrisbbreuer committed Oct 22, 2024
1 parent e06753d commit e73671d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 38 deletions.
8 changes: 4 additions & 4 deletions fixtures/output/example-0001.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export declare const someObject: {
someArray: Array<1 | 2 | 3>;
someNestedArray: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10>>;
someNestedArray2: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value'>;
someNestedArray3: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value', [11, 12, 13]'>;
someOtherNestedArray: Array<Array<'some text', 2, console.log, () => console.log('hello world'), helloWorld'>>;
someComplexArray: Array<Array<Object>>;
someNestedArray3: Array<Array<1 | 2 | 3> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10> | 'dummy value' | Array<11 | 12 | 13>>;
someOtherNestedArray: Array<Array<'some text' | 2 | (...args: any[]) => void | (...args: any[]) => void | unknown> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10>>;
someComplexArray: Array<Array<{ key: 'value' }> | Array<{ key2: 'value2' } | 'test' | 1000> | Array<'some string' | (...args: any[]) => void | unknown>>;
someObject: {
key: 'value';
};
Expand All @@ -29,7 +29,7 @@ export declare const someObject: {
nestedKey: (...args: any[]) => void;
};
};
someNestedObjectArray: Array<Object>;
someNestedObjectArray: Array<{ key: 'value' } | { key2: 'value2' }>;
someOtherObject: unknown;
someInlineCall2: (...args: any[]) => void;
someInlineCall3: (...args: any[]) => void;
Expand Down
85 changes: 51 additions & 34 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,24 +377,24 @@ export function inferArrayType(value: string): string {
if (elements.length === 0)
return 'never[]'

// For deeply nested arrays, handle each level properly
const isNestedArray = elements.some(el => el.trim().startsWith('['))
if (isNestedArray) {
const processedTypes = elements.map((element) => {
// Handle case where elements themselves are arrays
if (elements.some(el => el.trim().startsWith('['))) {
const nestedTypes = elements.map((element) => {
const trimmed = element.trim()
if (trimmed.startsWith('[')) {
const innerTypes = inferArrayType(trimmed)
return innerTypes
const nestedContent = extractNestedContent(trimmed, '[', ']')
if (nestedContent) {
const nestedElements = splitArrayElements(nestedContent)
return `Array<${nestedElements.map(ne => inferElementType(ne.trim())).join(' | ')}>`
}
}
return inferElementType(trimmed)
})

// Filter out any invalid types and create union
const validTypes = processedTypes.filter(type => type !== 'never' && type !== '')
return `Array<${[...new Set(validTypes)].join(' | ')}>`
return `Array<${nestedTypes.join(' | ')}>`
}

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

// Handle function expressions and references
if (
trimmed === 'console.log'
|| trimmed.endsWith('.log')
|| trimmed.includes('=>')
|| trimmed.includes('function')
) {
// Handle function references and calls
if (trimmed === 'console.log' || trimmed.endsWith('.log')) {
return '(...args: any[]) => void'
}

// Handle global references and unknown identifiers
if (trimmed.includes('.') || /^[a-z_]\w*$/i.test(trimmed)) {
// Handle arrow functions
if (trimmed.includes('=>')) {
const arrowFn = trimmed.match(/\(.*\)\s*=>\s*(.*)/)
return '(...args: any[]) => void'
}

// Handle function calls
if (trimmed.endsWith('()')) {
return 'unknown'
}

// Handle object references
if (trimmed.includes('.')) {
return 'unknown'
}

// Handle identifiers that might be undefined
if (/^[a-z_]\w*$/i.test(trimmed)) {
return 'unknown'
}

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

return inferElementType(trimmed)
}).filter(type => type !== 'never' && type !== '')
}).filter(type => type !== 'never')

return [...new Set(processedTypes)].join(' | ')
return processedTypes.join(' | ')
}

/**
Expand Down Expand Up @@ -510,17 +521,21 @@ export function splitArrayElements(content: string): string[] {
let inString = false
let stringChar = ''

for (const char of content) {
for (let i = 0; i < content.length; i++) {
const char = content[i]

// Handle string boundaries
if ((char === '"' || char === '\'') && !inString) {
inString = true
stringChar = char
}
else if (char === stringChar && !inString) {
inString = false
if ((char === '"' || char === '\'') && (i === 0 || content[i - 1] !== '\\')) {
if (!inString) {
inString = true
stringChar = char
}
else if (char === stringChar) {
inString = false
}
}

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

// Split elements only at top level
if (char === ',' && depth === 0 && !inString) {
if (current.trim())
if (current.trim()) {
elements.push(current.trim())
}
current = ''
}
else {
Expand All @@ -540,8 +556,9 @@ export function splitArrayElements(content: string): string[] {
}

// Add the last element
if (current.trim())
if (current.trim()) {
elements.push(current.trim())
}

return elements.filter(Boolean)
}
Expand Down

0 comments on commit e73671d

Please sign in to comment.