Skip to content

Latest commit

 

History

History
314 lines (265 loc) · 9.88 KB

File metadata and controls

314 lines (265 loc) · 9.88 KB

Type Information Extraction Exploration Summary

Overview

This exploration documents how mint-tsdocs extracts, analyzes, and processes type information from API Extractor's .api.json files. The codebase uses a sophisticated multi-layered system combining API model traversal, recursive type string parsing, and semantic enrichment.

Generated Reports

Two detailed reports have been created in /agent/reports/:

  1. type-extraction-analysis.md (27 KB)

    • Comprehensive 9-section analysis
    • Full code snippets and explanations
    • Deep dive into each component
    • Examples of type processing flows
  2. type-extraction-quick-reference.md (6 KB)

    • Quick lookup guide
    • File locations and entry points
    • Type pattern detection
    • Data flow examples
    • Caching strategy overview

Key Findings

1. Architecture (4 Core Components)

Component File Purpose
MarkdownDocumenter src/documenters/MarkdownDocumenter.ts Orchestrates generation, recursively processes API items
TemplateDataConverter src/templates/TemplateDataConverter.ts Converts ApiItem objects to template-friendly data structures
ObjectTypeAnalyzer src/utils/ObjectTypeAnalyzer.ts Parses type strings (primitives, arrays, unions, objects, generics)
DocumentationHelper src/utils/DocumentationHelper.ts Enriches type analysis with semantic meaning and JSDoc descriptions

2. How Nested Types Are Extracted

Entry Point: param.parameterTypeExcerpt.text or apiItem.excerpt.text

Pipeline:

Type String (e.g., "{ name: string; config?: { enabled: boolean } }")
    ↓
ObjectTypeAnalyzer.analyzeType()  [Recursive parsing]
    ↓
Detects pattern: object-literal
    ↓
_parseObjectLiteral() → Recursively extract properties
    ↓
For each property: analyzeType(propertyType)  [Recursive call]
    ↓
DocumentationHelper enriches with descriptions
    ↓
Templates format for MDX output

3. Type Pattern Recognition

The analyzer handles:

  • Primitives: string, number, boolean, void, any, never, unknown, null, undefined
  • Arrays: Type[] (recursive element analysis)
  • Unions: Type1 | Type2 (recursive component analysis)
  • Intersections: Type1 & Type2
  • Generics: Base (extracts parameters)
  • Object Literals: { prop: type; nested: { ... } } (recursive property extraction)

4. Key Files for Type Extraction

Type String Parsing

  • /work/mintlify-tsdocs/src/utils/ObjectTypeAnalyzer.ts (249 lines)
    • analyzeType(type: string): TypeAnalysis (lines 41-53)
    • _parseObjectLiteral(type: string): TypeAnalysis (lines 132-155)
    • _parseProperties(content: string): PropertyAnalysis[] (lines 160-186)
    • _splitBySemicolons(content: string): string[] (lines 191-217) - handles nested braces

API Model Conversion

  • /work/mintlify-tsdocs/src/templates/TemplateDataConverter.ts (345 lines)
    • convertApiItem(apiItem, options): ITemplateData (lines 21-79)
    • _createTableRows(apiItems, getLinkFilename): ITableRow[] (lines 149-162)
    • _createParameterRows(apiFunction, getLinkFilename): ITableRow[] (lines 164-189)
    • Type-specific handlers: _addClassData(), _addInterfaceData(), etc.

Semantic Enrichment

  • /work/mintlify-tsdocs/src/utils/DocumentationHelper.ts (179 lines)
    • analyzeTypeProperties(type, description, propertyPath): PropertyInfo (lines 34-125)
    • Supports nested properties via recursive PropertyAnalysis
    • Integrates JSDoc descriptions via propertyPath

Orchestration

  • /work/mintlify-tsdocs/src/documenters/MarkdownDocumenter.ts (2200+ lines)
    • generateFiles(): Promise<void> (lines 189-227)
    • _writeApiItemPageTemplate(apiItem, parentApiItem): Promise<void> (lines 241-322)
    • Recursively processes class/interface members

Caching

  • /work/mintlify-tsdocs/src/cache/TypeAnalysisCache.ts (148 lines)
    • LRU cache with 1000-item default capacity
    • Hit/miss tracking for statistics
  • /work/mintlify-tsdocs/src/cache/ApiResolutionCache.ts (173 lines)
    • LRU cache for API reference resolution

5. How Properties Are Extracted

For Classes/Interfaces:

// Member filtering by type
apiClass.members.filter(m => m.kind === ApiItemKind.Property)
apiInterface.members.filter(m => m.kind === ApiItemKind.PropertySignature)

// Type extraction
apiPropertyItem.propertyTypeExcerpt.text  // Raw type string
ApiOptionalMixin.isOptional              // Optional flag
ApiReadonlyMixin.isReadonly              // Readonly flag
ApiInitializerMixin.initializerExcerpt   // Default value

For Parameters:

apiFunction.parameters  // Array of ApiParameter objects

// Per parameter
param.parameterTypeExcerpt.text  // Type string
param.isOptional                 // Optional flag
param.tsdocParamBlock            // JSDoc @param docs

Recursive Processing:

// Example: Nested object in parameter
param.parameterTypeExcerpt.text = "{ name: string; config: { enabled: boolean } }"

// Step 1: ObjectTypeAnalyzer detects object-literal
// Step 2: _parseObjectLiteral() extracts properties:
//   - name (type: string, optional: false)
//   - config (type: object-literal with nested properties)
// Step 3: Recursively analyze config's type
// Step 4: Build nested structure

6. Current Limitations

  1. JSDoc Extraction (JsDocExtractor.ts)

    • Hardcoded descriptions only
    • Does not parse actual TypeScript source files
    • Limited to predefined property paths
  2. Type Linking (TemplateDataConverter.ts:283-286)

    • Not implemented (returns undefined)
    • Types don't resolve to their definitions
  3. Generic Type Parameters

    • Extracted but not deeply analyzed
    • Type parameter constraints not extracted
    • Record<K, V> not fully resolved
  4. Caching

    • Simple string-based keys
    • No TTL or auto-invalidation
    • Maximum 1000 types by default

7. Data Structures

TypeAnalysis (from ObjectTypeAnalyzer)

interface TypeAnalysis {
  type: 'primitive' | 'array' | 'union' | 'intersection' | 'generic' | 'object-literal' | 'unknown';
  name?: string;
  elementType?: TypeAnalysis;           // Arrays
  unionTypes?: TypeAnalysis[];          // Unions
  intersectionTypes?: TypeAnalysis[];   // Intersections
  baseType?: string;                    // Generics
  typeParameters?: string[];            // Generics
  properties?: PropertyAnalysis[];       // Objects
}

interface PropertyAnalysis {
  name: string;
  type: TypeAnalysis;                   // Recursive
  optional: boolean;
}

PropertyInfo (from DocumentationHelper)

interface PropertyInfo {
  name: string;
  type: string;
  description: string;
  required: boolean;
  deprecated: boolean;
  nestedProperties?: PropertyInfo[];    // Recursive
}

ITableRow (for templates)

interface ITableRow {
  title: string;
  titlePath?: string;
  modifiers?: string[];
  type?: string;
  typePath?: string;
  description?: string;
  isOptional?: boolean;
  isInherited?: boolean;
  isDeprecated?: boolean;
  defaultValue?: string;
}

8. Example: Processing a Complex Type

Input TypeScript:

function process(options: {
  name: string;
  timeout?: number;
  handlers: {
    onSuccess: (result: any) => void;
    onError?: (error: Error) => void;
  }[];
}): void

Extraction Flow:

  1. MarkdownDocumenter._createParameterRows() gets param.parameterTypeExcerpt.text
  2. Type string: "{ name: string; timeout?: number; handlers: { onSuccess: (result: any) => void; onError?: (error: Error) => void; }[]; }"
  3. ObjectTypeAnalyzer.analyzeType() parses as object-literal
  4. _parseObjectLiteral() extracts 3 properties:
    • name (primitive: string, required)
    • timeout (primitive: number, optional)
    • handlers (array of object-literal)
  5. For handlers array: recursively analyze element type (object-literal with 2 methods)
  6. DocumentationHelper.analyzeTypeProperties() enriches with descriptions
  7. Templates render parameter table with nested structure

Output Structure:

{
  name: '',
  type: 'object',
  nestedProperties: [
    {
      name: 'name',
      type: 'string',
      required: true,
      description: '...'
    },
    {
      name: 'timeout',
      type: 'number',
      required: false,
      description: '...'
    },
    {
      name: 'handlers',
      type: 'object[]',
      required: true,
      nestedProperties: [
        {
          name: 'onSuccess',
          type: '(result: any) => void',
          required: true
        },
        {
          name: 'onError',
          type: '(error: Error) => void',
          required: false
        }
      ]
    }
  ]
}

9. Performance Optimizations

Caching:

  • TypeAnalysisCache: 1000-item LRU for type analysis
  • ApiResolutionCache: 500-item LRU for API reference resolution
  • Both track hit/miss ratios

Statistics Available:

cache.getStats()  {
  size: number;
  maxSize: number;
  hitRate: number;
  hitCount: number;
  missCount: number;
  enabled: boolean;
}

Summary

The type extraction system in mint-tsdocs is well-architected for documentation generation:

  1. Leverages API Extractor - Uses @microsoft/api-extractor-model for accurate type data
  2. Recursive Design - Handles nested objects, arrays, and complex types elegantly
  3. Caching for Performance - LRU caches reduce redundant analysis
  4. Semantic Enrichment - Adds descriptions and metadata beyond raw types
  5. Template Integration - Structured data designed for easy template rendering

Areas for Enhancement

  1. Parse actual TypeScript source for JSDoc descriptions
  2. Implement type linking to definitions
  3. Better handling of generic type parameters
  4. Circular reference detection
  5. Support for conditional/mapped types

Report Generated: November 19, 2025 Explored Files: 7 core files + 3 cache/utility files Total Code Analyzed: ~3,500+ lines of type extraction logic