Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbbreuer committed Oct 31, 2024
1 parent e892723 commit 3420eb0
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 21 deletions.
44 changes: 32 additions & 12 deletions fixtures/output/variable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ export declare const someObject: {
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' | Array<11 | 12 | 13>>;
someOtherNestedArray: Array<Array<'some text' | 2 | unknown | (() => void) | unknown> | Array<4 | 5 | 6 | 7 | 8 | 9 | 10>>;
someComplexArray: Array<Array<{
key: 'value'
}> | Array<{
key2: 'value2'
} | 'test' | 1000> | Array<'some string' | unknown | unknown>>;
someOtherNestedArray: Array<
Array<'some text' | 2 | unknown | (() => void) | unknown> |
Array<4 | 5 | 6 | 7 | 8 | 9 | 10>
>;
someComplexArray: Array<
Array<
{
key: 'value'
}
> |
Array<
{
key2: 'value2'
} |
'test' |
1000
> |
Array<'some string' | unknown | unknown>
>;
someObject: {
key: 'value'
};
Expand All @@ -31,11 +44,14 @@ export declare const someObject: {
nestedKey2: () => unknown
}
};
someNestedObjectArray: Array<{
key: 'value'
} | {
key2: 'value2'
}>;
someNestedObjectArray: Array<
{
key: 'value'
} |
{
key2: 'value2'
}
>;
someOtherObject: unknown;
someInlineCall2: unknown;
someInlineCall3: unknown
Expand All @@ -46,7 +62,11 @@ export declare const defaultHeaders: {
};
declare const dtsConfig: DtsGenerationConfig;
export declare const complexArrays: {
matrix: Array<Array<1 | 2 | Array<3 | 4 | Array<5 | 6>>> | Array<'a' | 'b' | Array<'c' | 'd'>> | Array<true | Array<false | Array<true>>>>;
matrix: Array<
Array<1 | 2 | Array<3 | 4 | Array<5 | 6>>> |
Array<'a' | 'b' | Array<'c' | 'd'>> |
Array<true | Array<false | Array<true>>>
>;
tuples: Array<readonly [1, 'string', true] | readonly ['literal', 42, false]>;
mixedArrays: Array<unknown | unknown | ((...args: any[]) => unknown) | ((...args: any[]) => unknown)>
};
Expand Down
44 changes: 35 additions & 9 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,12 +560,15 @@ function inferValueType(value: string): string {
/**
* Infer array type from array literal with support for nested arrays and mixed elements
*/
function inferArrayType(value: string, state?: ProcessingState): string {
function inferArrayType(value: string, state?: ProcessingState, indentLevel = 0): string {
debugLog(state, 'infer-array', `Inferring array type for: ${value}`)
const content = value.slice(1, -1).trim()
if (!content)
return 'unknown[]'

const baseIndent = ' '.repeat(indentLevel)
const elementIndent = ' '.repeat(indentLevel + 1)

// Handle const assertions first
const elements = splitArrayElements(content, state)
const allConstTuples = elements.every(el => el.trim().endsWith('as const'))
Expand All @@ -584,12 +587,12 @@ function inferArrayType(value: string, state?: ProcessingState): string {

// Handle nested arrays
if (trimmed.startsWith('[')) {
return inferArrayType(trimmed, state)
return inferArrayType(trimmed, state, indentLevel + 1)
}

// Handle objects
// Handle objects with proper indentation
if (trimmed.startsWith('{')) {
return inferComplexObjectType(trimmed, state)
return inferComplexObjectType(trimmed, state, indentLevel + 1)
}

// Handle function expressions - always parenthesize
Expand All @@ -607,7 +610,23 @@ function inferArrayType(value: string, state?: ProcessingState): string {
return normalizeTypeReference(trimmed)
})

return `Array<${elementTypes.join(' | ')}>`
// Format the array type with proper indentation
const types = elementTypes.filter(Boolean)
if (types.length === 0)
return 'unknown[]'

// Check if we need multiline formatting
const needsMultiline = types.some(type =>
type.includes('\n')
|| type.includes('{')
|| type.length > 40,
)

if (needsMultiline) {
return `Array<\n${elementIndent}${types.join(` |\n${elementIndent}`)}\n${baseIndent}>`
}

return `Array<${types.join(' | ')}>`
}

/**
Expand Down Expand Up @@ -656,6 +675,12 @@ function inferComplexObjectType(value: string, state?: ProcessingState, indentLe
if (value.startsWith('{')) {
formattedValue = inferComplexObjectType(value, state, indentLevel + 1)
}
// Format array types with proper indentation
else if (value.startsWith('Array<')) {
// Extract the array content and re-indent it
const arrayContent = value.slice(6, -1)
formattedValue = `Array<${arrayContent}>`
}

return `${propIndent}${formattedKey}: ${formattedValue}`
}).join(';\n')
Expand Down Expand Up @@ -1476,7 +1501,7 @@ function processObjectProperties(content: string, state?: ProcessingState): Arra
return properties
}

function processProperty(key: string, value: string, state?: ProcessingState): { key: string, value: string } {
function processProperty(key: string, value: string, state?: ProcessingState, indentLevel = 0): { key: string, value: string } {
const cleanKey = key.trim().replace(/^['"](.*)['"]$/, '$1')
const cleanValue = value.trim()

Expand All @@ -1488,18 +1513,18 @@ function processProperty(key: string, value: string, state?: ProcessingState): {
return { key: name, value: signature }
}

// Handle arrays
// Handle arrays with proper indentation
if (cleanValue.startsWith('[')) {
debugLog(state, 'process-array', `Processing array in property "${cleanKey}"`)
return { key: cleanKey, value: inferArrayType(cleanValue, state) }
return { key: cleanKey, value: inferArrayType(cleanValue, state, indentLevel) }
}

// Handle object literals with proper indentation
if (cleanValue.startsWith('{')) {
debugLog(state, 'process-object', `Processing nested object in property "${cleanKey}"`)
return {
key: cleanKey,
value: inferComplexObjectType(cleanValue, state, 0),
value: inferComplexObjectType(cleanValue, state, indentLevel),
}
}

Expand All @@ -1524,6 +1549,7 @@ function processProperty(key: string, value: string, state?: ProcessingState): {
return { key: cleanKey, value: 'unknown' }
}

// Default case
return { key: cleanKey, value: 'unknown' }
}

Expand Down

0 comments on commit 3420eb0

Please sign in to comment.