npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

typescript-api-extractor

v1.0.0-beta.6

Published

Extracts API description from TypeScript code

Downloads

61,568

Readme

TypeScript API Extractor

npm version TypeScript License: MIT

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.

Features

  • 🔍 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

Installation

npm install typescript-api-extractor

or with yarn:

yarn add typescript-api-extractor

or with pnpm:

pnpm add typescript-api-extractor

Usage

import {
	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);
	}
}

API Reference

createProgram

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.

loadConfig(tsConfigPath: string)

Loads and parses a TypeScript configuration file.

  • Parameters:
    • tsConfigPath: Path to the tsconfig.json file
  • Returns: { options: CompilerOptions, fileNames: string[] }

parseFile(filePath: string, options: CompilerOptions, parserOptions?: ParserOptions)

Parses a single TypeScript file and returns the extracted API information.

  • Parameters:
    • filePath: Path to the TypeScript file to parse
    • options: TypeScript compiler options
    • parserOptions: Optional parser configuration
  • Returns: ResolvedModuleNode by default, or SyntaxOnlyModuleNode when parserOptions.typeOperatorOutput is the literal 'syntaxOnly'. A dynamic ParserOptions value returns their union.

parseFromProgram(filePath: string, program: Program, parserOptions?: ParserOptions)

Parses a file from an existing TypeScript program for better performance when parsing multiple files.

  • Parameters:
    • filePath: Path to the file to parse
    • program: TypeScript program instance
    • parserOptions: Optional parser configuration
  • Returns: ResolvedModuleNode by default, or SyntaxOnlyModuleNode when parserOptions.typeOperatorOutput is the literal 'syntaxOnly'. A dynamic ParserOptions value returns their union.

Configuration Options

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;
		propertyDepth: number;
	}) => boolean | undefined;
	includeExternalTypes?: boolean;
	typeOperatorOutput?: 'resolved' | 'syntaxOnly';
	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;
}

shouldResolveObject decides whether an object's shape is expanded or reduced to a bare object. Returning undefined falls back to (propertyDepth === 0 || propertyCount <= 50) && depth <= 10.

depth counts every type on the resolution stack, while propertyDepth counts only the property (and index signature) values traversed to reach the object. A propertyDepth of 0 means the object is the export's own type or something reached from it through composition alone - aliases, unions, intersections, and the parameter and return types of its call signatures. The default rule applies the property-count limit only above that, so a large component prop list is reported in full while its individual props stay bounded.

When onWarning is omitted, recoverable parser warnings are printed with console.warn. Provide onWarning to collect or format them yourself.

Output Format

The parser returns a module object with the following structure. The default ResolvedModuleNode and opt-in SyntaxOnlyModuleNode types are recursively mode-aware versions of ModuleNode; both remain structurally compatible with the runtime model.

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.

Type Operators

Authored keyof expressions are represented without expanding away their syntax:

interface TypeOperatorNode {
	kind: 'typeOperator';
	operator: 'keyof';
	type: TypeNode;
	resolvedType?: TypeNode;
	resolutionKind?: 'exact' | 'baseConstraint' | 'fallback';
}

type ResolvedTypeOperatorNode = Omit<TypeOperatorNode, 'resolvedType' | 'resolutionKind'> & {
	resolvedType: TypeNode;
	resolutionKind: 'exact' | 'baseConstraint' | 'fallback';
};

type SyntaxOnlyTypeOperatorNode = Omit<TypeOperatorNode, 'resolvedType' | 'resolutionKind'> & {
	resolvedType?: never;
	resolutionKind?: never;
};

The exported TypeOperatorNode class represents both runtime modes, so its payload fields are optional. Parser entry points correlate them recursively: default and literal 'resolved' calls return ResolvedModuleNode, literal 'syntaxOnly' calls return SyntaxOnlyModuleNode, and a dynamic mode returns their union.

Type-query operands retain their authored expression without expanding the queried value shape:

interface TypeQueryNode {
	kind: 'typeQuery';
	expressionName: string;
}

For example, the type of keyof typeof value is a TypeQueryNode whose expressionName is value.

Readonly arrays and tuples expose isReadonly: true in their public output, including when they are nested inside a preserved operator:

interface ArrayNode {
	kind: 'array';
	typeName?: TypeName;
	elementType: TypeNode;
	isReadonly?: true;
}

interface TupleNode {
	kind: 'tuple';
	typeName?: TypeName;
	types: TypeNode[];
	isReadonly?: true;
}

The optional field is omitted for mutable containers and serialized as true for readonly containers. This keeps rendered operands and their resolved key sets consistent.

  • type is the authored operand. Named object operands are intentionally shallow references because expanding their properties does not change the operator or its key result.
  • resolvedType is the checker result used to describe the keys available from the operator. Set typeOperatorOutput: 'syntaxOnly' to omit this potentially large payload together with resolutionKind; the default is 'resolved'.
  • resolutionKind: 'exact' means resolvedType is the concrete result.
  • resolutionKind: 'baseConstraint' means the operand is still generic, so resolvedType is the best available base constraint rather than its eventual instantiated result. For example, keyof T commonly resolves to string | number | symbol at extraction time.
  • resolutionKind: 'fallback' means the checker exposed neither a usable constraint nor a result the model can represent exactly; unsupported concrete results are represented by any and emit an unsupported-type-fallback warning.

Preservation follows authored operators through the supported reference, container, mapped, indexed-access, conditional-branch, and heritage paths. It does not reconstruct operators after TypeScript selector or inference utilities have erased their source syntax. For example, ReturnType, Parameters, Awaited, ConstructorParameters, ThisParameterType, and user-authored conditional infer selectors can expose only their reduced semantic result.

Example Output

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"
						}
					}
				]
			}
		}
	]
}

Technical Notes

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.

Architecture Principles

  • Keep normalization and construction as separate phases. Export parsing first creates ExportDescriptor records, then converts them into ExportNode models 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 ScopedParserContext scope helpers for symbol stacks, source-node stacks, and type-parameter substitutions instead of mutating ambient parser state directly. The public ParserContext stays 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.

Entry Points

  • src/parsers/moduleParser.ts and src/parsers/exportParser.ts walk source files and exported declarations.
  • src/parsers/exportDescriptors.ts normalizes export symbols into ExportDescriptor records 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.ts applies post-export transforms after generic export nodes are built. Today it runs the React component transform from componentParser.ts.
  • src/parsers/componentParser.ts contains React component-specific extraction and should remain a transform policy rather than a generic export parser. It recognizes both a single function type and a union of them, so a polymorphic component whose arms differ per prop form still reports one merged prop list. Return types are matched by name rather than by resolved node kind, so includeExternalTypes changes how much detail the output carries without changing what counts as a component.
  • src/parsers/typeResolver.ts is 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/parserContextFactory.ts constructs the scoped parser context shared by production entry points and focused parser tests, including balanced diagnostic and substitution scopes.

Type Resolution

  • src/parsers/typeResolutionSession.ts owns 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.ts defines the contracts shared by the resolver pipeline. Resolvers receive a TypeResolutionRequest and a TypeResolutionSession.
  • ScopedParserContext (in src/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 public ParserContext (exported from src/parser.ts) stays focused on observable parser state and options.
  • src/parsers/typeResolutionDiagnostics.ts centralizes recoverable fallback warnings, including source-location selection and TypeScript flag formatting.
  • src/parsers/typeResolutionUtils.ts isolates TypeScript internal API access, such as private type IDs and shallow cycle placeholders.
  • src/parsers/authoredTypeReferenceBindings.ts derives shared authored and semantic generic bindings across references and interface/class heritage so member, signature, and container resolution use the same specialization.
  • src/parsers/typeParameterBindings.ts pairs semantic arguments and authored argument nodes with every checker symbol that can represent a generic parameter during nested resolution.
  • src/parsers/typeContainerUtils.ts centralizes compiler-backed array and tuple identity, readonly-state, and tuple-element syntax helpers shared by container resolvers.
  • src/parsers/sourceFileUtils.ts owns the deliberately distinct broad and path-segment-based node_modules policies used by semantic and authored-syntax traversal.

Type-Class Resolvers

All resolver pipeline modules live in src/parsers/typeResolvers/.

  • index.ts is the ordered resolver registry. Resolver order is meaningful: syntax-first operators and specific shapes should appear before semantic fallbacks that would discard authored syntax.
  • authoredTypeAlias.ts replays alias bodies whose supported syntax contains keyof, carries generic substitutions across local and relative-import alias chains, and preserves source-only preflight checks where export normalization must not perturb TypeScript's lazy caches.
  • referencedTypeAlias.ts centralizes type-alias lookup for ordinary references and import() type references used by container and operator helpers.
  • arrayTypeResolver.ts handles arrays and element-type recursion.
  • classTypeResolver.ts handles class detection, constructor model assembly, constructor documentation, class members, static members, and class type parameters.
  • enumTypeResolver.ts handles enum-like flags and enum symbol/member extraction.
  • functionTypeResolver.ts handles callable type selection and function model assembly.
  • intrinsicTypeResolver.ts handles all primitive/intrinsic flags such as string, number, boolean, void, any, unknown, null, and never.
  • intersectionTypeResolver.ts handles intersection members and any merged callable/object shape TypeScript exposes for the intersection.
  • literalTypeResolver.ts handles string/number/bigint/boolean literal nodes.
  • objectTypeResolver.ts handles object-like types, object properties, index signatures, mapped-type index signatures, and object-keyword fallback.
  • tupleTypeResolver.ts handles tuple element resolution and tuple arity.
  • typeOperatorTypeResolver.ts preserves authored keyof syntax, resolves its operand and semantic result separately, and records whether that result is exact, a base constraint, or a fallback.
  • typeOperatorTypeNodes.ts contains the shared syntax helpers used to find and propagate authored keyof nodes through parenthesized and nested type syntax.
  • unionTypeResolver.ts owns union-specific behavior, including preserving authored union member order and overlapping type-operator members from TypeNodes.
  • specialTypeResolvers.ts handles TypeScript-internal or context-sensitive shapes such as type parameters, conditional types, indexed access types, and substitution fallbacks.
  • externalTypeResolver.ts contains the external-type policy used when includeExternalTypes is disabled.
  • signatureTypeParameterNodes.ts is a shared helper for signature type parameter metadata used by class and function resolvers.
  • signatureParser.ts owns 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.

Model Construction

  • Classes in src/models/types/ are model DTOs with rendering helpers such as toString(). They should not own parser policy. Compound constructors are the only exception: they delegate member normalization to typeCanonicalizer so all callers get the same union/intersection behavior from normal construction.
  • src/models/typeCanonicalizer.ts owns compound member normalization such as flattening nested compounds, simplifying boolean literal unions, removing redundant never, keeping nullish members at the end, and deduplicating members. It exports the singleton typeCanonicalizer; the implementation class is internal so callers use one shared normalization policy.
  • src/models/typeEquivalence.ts owns structural equivalence checks used by canonicalization, including the intentional rule that unaliased any can act as a wildcard when choosing between duplicate generated signatures. It exports the singleton typeEquivalenceChecker; the implementation class is internal.

Shared Parser Helpers

  • common.ts contains TypeScript name and type-argument helpers shared across parser layers.
  • documentationParser.ts converts TypeScript documentation, JSDoc metadata, and parameter documentation into model documentation nodes.

Requirements

  • Node.js: >= 22

License

This project is licensed under the terms of the MIT license.

Acknowledgments

This project was started as a fork of typescript-to-proptypes created by Kristoffer K..