A utility for extracting API descriptions from TypeScript definitions using the TypeScript Compiler API. This tool analyzes TypeScript source code and generates structured metadata about exported functions, components, interfaces, types, and more.
- 🔍 Extract API information from TypeScript source files
- ⚛️ React component analysis with prop types and documentation
- 🏷️ Type definitions including interfaces, enums, and type aliases
- 📝 JSDoc comments parsing and extraction
- 🔗 Reference resolution for complex type relationships
- 🎯 Selective parsing of specific files or entire projects
npm install typescript-api-extractoror with yarn:
yarn add typescript-api-extractoror with pnpm:
pnpm add typescript-api-extractorimport {
createProgram,
loadConfig,
parseFromProgram,
type ModuleNode,
} from 'typescript-api-extractor';
// Load TypeScript configuration
const config = loadConfig('./tsconfig.json');
const program = createProgram(config.fileNames, config.options);
// Parse all files in the project
for (const file of config.fileNames) {
try {
const moduleInfo: ModuleNode = parseFromProgram(file, program);
console.log(`Extracted API from ${file}:`, moduleInfo);
} catch (error) {
console.error(`Failed to parse ${file}:`, error);
}
}Re-export of TypeScript’s createProgram from the TypeScript version bundled with typescript-api-extractor. It has the same overloads/signature as typescript.createProgram and returns a Program.
Loads and parses a TypeScript configuration file.
- Parameters:
tsConfigPath: Path to thetsconfig.jsonfile
- Returns:
{ options: CompilerOptions, fileNames: string[] }
Parses a single TypeScript file and returns the extracted API information.
- Parameters:
filePath: Path to the TypeScript file to parseoptions: TypeScript compiler optionsparserOptions: Optional parser configuration
- Returns:
ModuleNode
Parses a file from an existing TypeScript program for better performance when parsing multiple files.
- Parameters:
filePath: Path to the file to parseprogram: TypeScript program instanceparserOptions: Optional parser configuration
- Returns:
ModuleNode
The parser accepts optional configuration through the ParserOptions interface:
interface ParserOptions {
shouldInclude?: (data: { name: string; depth: number }) => boolean | undefined;
shouldResolveObject?: (data: {
name: string;
propertyCount: number;
depth: number;
}) => boolean | undefined;
includeExternalTypes?: boolean;
onWarning?: (warning: ParserWarning) => void;
}
type ParserWarning =
| UnsupportedTypeFallbackWarning
| MissingEnumDeclarationWarning
| MissingDefaultExportSymbolWarning;
interface ParserWarningBase {
message: string;
filePath: string;
line: number;
column: number;
parsedSymbolStack: string[];
}
interface UnsupportedTypeFallbackWarning extends ParserWarningBase {
code: 'unsupported-type-fallback';
typeFlags: string[];
typeText: string;
sourceText?: string;
}
interface MissingEnumDeclarationWarning extends ParserWarningBase {
code: 'missing-enum-declaration';
enumName: string;
}
interface MissingDefaultExportSymbolWarning extends ParserWarningBase {
code: 'missing-default-export-symbol';
sourceText: string;
}When onWarning is omitted, recoverable parser warnings are printed with
console.warn. Provide onWarning to collect or format them yourself.
The parser returns a ModuleNode object with the following structure:
interface ModuleNode {
name: string;
exports: ExportNode[];
}
interface ExportNode {
name: string;
type: TypeNode;
documentation?: DocumentationNode;
}TypeNode represents a TypeScript type. There are multiple classes of types. See the contents of the src/models/types directory to discover them.
For a React component like this:
interface Props {
/** The title to display */
title: string;
/** Whether the component is disabled */
disabled?: boolean;
}
export function MyComponent(props: Props) {
return <div>{props.title}</div>;
}ModuleNode.name is the parsed file path relative to compilerOptions.rootDir,
including the file extension. For a file at src/MyComponent.ts, the extractor
would produce:
{
"name": "src/MyComponent.ts",
"exports": [
{
"name": "MyComponent",
"type": {
"kind": "component",
"typeName": {
"name": "MyComponent"
},
"props": [
{
"name": "title",
"type": {
"kind": "intrinsic",
"intrinsic": "string"
},
"optional": false,
"documentation": {
"description": "The title to display"
}
},
{
"name": "disabled",
"type": {
"kind": "intrinsic",
"intrinsic": "boolean"
},
"optional": true,
"documentation": {
"description": "Whether the component is disabled"
}
}
]
}
}
]
}The parser code is split into a few layers. Type-class modules live in the resolver pipeline: each one chooses whether a TypeScript type shape applies and constructs the corresponding output model node. Shared helpers exist only for substructures that are reused across multiple type classes.
- Keep normalization and construction as separate phases. Export parsing first
creates
ExportDescriptorrecords, then converts them intoExportNodemodels once export targeting, namespace metadata, and re-export metadata are stable. - Keep type resolution as an ordered pipeline. Resolver order is observable for overlapping TypeScript shapes, so broad fallback resolvers should stay behind more specific resolvers.
- Keep parser context scoped. Parser code should use the internal
ScopedParserContextscope helpers for symbol stacks, source-node stacks, and type-parameter substitutions instead of mutating ambient parser state directly. The publicParserContextstays the observable parser state and options shape. - Keep model policy centralized. Type model classes are DTO-like and can render themselves, while compound normalization and structural equivalence live in dedicated model helpers.
src/parsers/moduleParser.tsandsrc/parsers/exportParser.tswalk source files and exported declarations.src/parsers/exportDescriptors.tsnormalizes export symbols intoExportDescriptorrecords before any output model nodes are built. It owns export-specifier targeting, namespace merging, re-export metadata, export type acquisition, and recoverable export warnings.src/parsers/exportTransforms.tsapplies post-export transforms after generic export nodes are built. Today it runs the React component transform fromcomponentParser.ts.src/parsers/componentParser.tscontains React component-specific extraction and should remain a transform policy rather than a generic export parser.src/parsers/typeResolver.tsis the public type-resolution facade used by the rest of the parser. It should stay small; the resolver implementation lives in the session and resolver modules.
src/parsers/typeResolutionSession.tsowns cross-cutting resolution mechanics: caching, recursion guards, type-parameter substitutions, warning replay, and the active resolver callback used by nested type-class handlers and helpers.src/parsers/typeResolutionTypes.tsdefines the contracts shared by the resolver pipeline. Resolvers receive aTypeResolutionRequestand aTypeResolutionSession.ScopedParserContext(insrc/parserContext.ts) exposes scoped parser-context helpers for diagnostic symbol scopes, diagnostic source-node scopes, and temporary type-parameter substitutions. Parser code should use these helpers instead of manually pushing and popping diagnostic stacks or swapping substitution maps. The publicParserContext(exported fromsrc/parser.ts) stays focused on observable parser state and options.src/parsers/typeResolutionDiagnostics.tscentralizes recoverable fallback warnings, including source-location selection and TypeScript flag formatting.src/parsers/typeResolutionUtils.tsisolates TypeScript internal API access, such as private type IDs and shallow cycle placeholders.
All resolver pipeline modules live in src/parsers/typeResolvers/.
index.tsis the ordered resolver registry. Resolver order is meaningful: specific shapes should appear before broader fallbacks.arrayTypeResolver.tshandles arrays and element-type recursion.classTypeResolver.tshandles class detection, constructor model assembly, constructor documentation, class members, static members, and class type parameters.enumTypeResolver.tshandles enum-like flags and enum symbol/member extraction.functionTypeResolver.tshandles callable type selection and function model assembly.intrinsicTypeResolver.tshandles all primitive/intrinsic flags such asstring,number,boolean,void,any,unknown,null, andnever.intersectionTypeResolver.tshandles intersection members and any merged callable/object shape TypeScript exposes for the intersection.literalTypeResolver.tshandles string/number/bigint/boolean literal nodes.objectTypeResolver.tshandles object-like types, object properties, index signatures, mapped-type index signatures, and object-keyword fallback.tupleTypeResolver.tshandles tuple element resolution and tuple arity.unionTypeResolver.tsowns union-specific behavior, including preserving authored union member order fromTypeNodes.specialTypeResolvers.tshandles TypeScript-internal or context-sensitive shapes such as type parameters, conditional types, indexed access types, and substitution fallbacks.externalTypeResolver.tscontains the external-type policy used whenincludeExternalTypesis disabled.signatureTypeParameterNodes.tsis a shared helper for signature type parameter metadata used by class and function resolvers.signatureParser.tsowns shared function-like signature parsing: call signatures, parameters, parameter docs/defaults, and return types used by callable exports, constructors, and class methods.
A resolver should answer, "Does this ts.Type shape apply, and if so, which
model node should represent it?" It should keep pipeline concerns such as
ordering, fallback choice, and session recursion explicit. If it needs nested
type resolution, it should use the active resolver callback from the current
TypeResolutionSession instead of importing resolveType directly.
- Classes in
src/models/types/are model DTOs with rendering helpers such astoString(). They should not own parser policy. Compound constructors are the only exception: they delegate member normalization totypeCanonicalizerso all callers get the same union/intersection behavior from normal construction. src/models/typeCanonicalizer.tsowns compound member normalization such as flattening nested compounds, simplifying boolean literal unions, removing redundantnever, keeping nullish members at the end, and deduplicating members. It exports the singletontypeCanonicalizer; the implementation class is internal so callers use one shared normalization policy.src/models/typeEquivalence.tsowns structural equivalence checks used by canonicalization, including the intentional rule that unaliasedanycan act as a wildcard when choosing between duplicate generated signatures. It exports the singletontypeEquivalenceChecker; the implementation class is internal.
common.tscontains TypeScript name and type-argument helpers shared across parser layers.documentationParser.tsconverts TypeScript documentation, JSDoc metadata, and parameter documentation into model documentation nodes.
- Node.js: >= 22
This project is licensed under the terms of the MIT license.
This project was started as a fork of typescript-to-proptypes created by Kristoffer K..