diff --git a/packages/titanium-docgen/generators/typescript_generator.js b/packages/titanium-docgen/generators/typescript_generator.js index 0518e93..1d4234b 100644 --- a/packages/titanium-docgen/generators/typescript_generator.js +++ b/packages/titanium-docgen/generators/typescript_generator.js @@ -175,7 +175,9 @@ class DocsParser { // skip bundled documentation for modules and Node.js shims return; } - const namespaceParts = typeInfo.name.split('.'); + // Handle generic types by extracting the base type name before the first '<' + const typeName = typeInfo.name.split('<')[0]; + const namespaceParts = typeName.split('.'); namespaceParts.pop(); if (skipApis.includes(typeInfo.name)) { return; @@ -622,7 +624,17 @@ class GlobalTemplateWriter { if (Array.isArray(docType)) { const normalizedTypes = docType.map(typeName => this.normalizeType(typeName)); - return normalizedTypes.includes('any') ? 'any' : normalizedTypes.join(' | '); + if (normalizedTypes.includes('any')) { + return 'any'; + } + // Parenthesize function types in unions to avoid TypeScript syntax errors + const parenthesizedTypes = normalizedTypes.map(type => { + if (type.includes(') => ')) { + return `(${type})`; + } + return type; + }); + return parenthesizedTypes.join(' | '); } const lessThanIndex = docType.indexOf('<'); @@ -649,6 +661,9 @@ class GlobalTemplateWriter { } } else if (baseType === 'Dictionary') { return `Dictionary<${subType}>`; + } else if (baseType === 'Promise') { + // Use standard Promise generic syntax + return `Promise<${subTypes.join(', ')}>`; } } diff --git a/packages/titanium-docgen/validate.js b/packages/titanium-docgen/validate.js index 3c4c17b..f879773 100644 --- a/packages/titanium-docgen/validate.js +++ b/packages/titanium-docgen/validate.js @@ -434,8 +434,12 @@ function validateDataType(type, fullTypeContext) { // Should it have been written as a complex type? if (common.COMPLEX_TYPES.has(type)) { const argCount = common.COMPLEX_TYPES.get(type); // may be 0 if Function/Callback - // Enforce as ERROR if Promise/Set/Map doesn't have exact generic type count - const severity = [ 'Map', 'Set', 'Promise' ].includes(type) ? ERROR : WARNING; + // Skip validation for Promise to allow Promise without generics (Promise not supported by build system) + if (type === 'Promise') { + return errors; + } + // Enforce as ERROR if Set/Map doesn't have exact generic type count + const severity = [ 'Map', 'Set' ].includes(type) ? ERROR : WARNING; errors.push(new Problem(`${type} ${severity === ERROR ? 'must' : 'should'} have ${argCount || 'any number of'} generic type(s) specified, but had 0: ${fullTypeContext || type}`, severity)); } else if (type === 'Object') { // Warn about generic Object types (Dictionary is handled above as a complex type)