Create api documentation for TypeScript projects.
—
Serialization system for converting reflections to/from JSON format, enabling data exchange, custom processing workflows, and integration with external tools.
Main serializer that converts TypeDoc reflections to JSON format for storage, transmission, or external processing.
/**
* Serializer converts reflections to JSON format
*/
class Serializer extends AbstractComponent<Application, SerializerEvents> {
/** Application instance */
readonly application: Application;
/**
* Convert project reflection to JSON object
* @param project - Project reflection to serialize
* @param out - Output directory path for relative path resolution
* @returns JSON representation of project
*/
projectToObject(project: ProjectReflection, out: string): JSONOutput.ProjectReflection;
/**
* Convert any value to JSON-serializable object
* @param value - Value to serialize
* @returns JSON-serializable representation
*/
toObject(value: unknown): unknown;
/**
* Add custom serializer component
* @param name - Component name
* @param component - Serializer component
*/
addComponent(name: string, component: SerializerComponent): void;
/**
* Remove serializer component
* @param name - Component name to remove
*/
removeComponent(name: string): void;
/**
* Get serializer component
* @param name - Component name
* @returns Serializer component or undefined
*/
getComponent(name: string): SerializerComponent | undefined;
}Usage Examples:
import { Application, Serializer } from "typedoc";
const app = await Application.bootstrap({
entryPoints: ["src/index.ts"],
});
const project = await app.convert();
if (project) {
// Serialize project to JSON
const serializer = app.serializer;
const jsonProject = serializer.projectToObject(project, "docs");
// Save to file
await writeFile("docs/api.json", JSON.stringify(jsonProject, null, 2));
// Serialize individual reflection
const mainModule = project.children?.[0];
if (mainModule) {
const jsonModule = serializer.toObject(mainModule);
console.log("Serialized module:", jsonModule);
}
}Deserializer that reconstructs TypeDoc reflections from JSON format for loading saved documentation data.
/**
* Deserializer reconstructs reflections from JSON format
*/
class Deserializer {
/** Application instance */
readonly application: Application;
/** Deserializer components */
readonly components: Map<string, DeserializerComponent>;
/**
* Create deserializer instance
* @param application - Application instance
*/
constructor(application: Application);
/**
* Revive project reflection from JSON
* @param project - JSON project data
* @param name - Optional project name override
* @returns Reconstructed project reflection
*/
reviveProject(project: JSONOutput.ProjectReflection, name?: string): ProjectReflection;
/**
* Revive any object from JSON representation
* @param obj - JSON object to revive
* @param root - Root object for context
* @returns Revived object
*/
revive<T>(obj: any, root: T): T;
/**
* Add custom deserializer component
* @param name - Component name
* @param component - Deserializer component
*/
addComponent(name: string, component: DeserializerComponent): void;
/**
* Remove deserializer component
* @param name - Component name to remove
*/
removeComponent(name: string): void;
/**
* Get deserializer component
* @param name - Component name
* @returns Deserializer component or undefined
*/
getComponent(name: string): DeserializerComponent | undefined;
}Usage Examples:
import { Application, Deserializer } from "typedoc";
import { readFile } from "fs/promises";
const app = await Application.bootstrap();
// Load JSON data
const jsonData = await readFile("docs/api.json", "utf8");
const jsonProject = JSON.parse(jsonData);
// Deserialize back to reflections
const deserializer = new Deserializer(app);
const project = deserializer.reviveProject(jsonProject);
console.log(`Revived project: ${project.name}`);
console.log(`Modules: ${project.children?.length}`);
// Use revived project for rendering or analysis
await app.generateDocs(project, "revived-docs");Events fired during serialization process for customization and plugin integration.
/**
* Event fired during serialization of individual objects
*/
class SerializeEvent extends Event {
/** Object being serialized */
readonly obj: unknown;
/** JSON output being built */
output: unknown;
/**
* Create serialize event
* @param name - Event name
* @param obj - Object being serialized
* @param output - JSON output
*/
constructor(name: string, obj: unknown, output: unknown);
}
/**
* Events fired during serialization
*/
interface SerializerEvents {
/** Begin serialization */
BEGIN: [SerializeEvent];
/** End serialization */
END: [SerializeEvent];
/** Serialize specific object */
SERIALIZE: [SerializeEvent];
}Component system for extending serialization behavior for custom types and data.
/**
* Component interface for custom serialization
*/
interface SerializerComponent {
/**
* Serialize object to JSON representation
* @param instance - Object instance to serialize
* @param obj - Current JSON object being built
* @returns Modified JSON object
*/
serializeObject(instance: unknown, obj: any): any;
/**
* Serialize group of objects
* @param instance - Object instance
* @param obj - JSON object
* @returns Modified JSON object
*/
serializeGroup?(instance: unknown, obj: any): any;
/**
* Serialize group member
* @param instance - Object instance
* @param obj - JSON object
* @returns Modified JSON object
*/
serializeGroupMember?(instance: unknown, obj: any): any;
}
/**
* Component interface for custom deserialization
*/
interface DeserializerComponent {
/**
* Deserialize object from JSON representation
* @param instance - Object instance being built
* @param obj - JSON data
* @returns Modified object instance
*/
deserializeObject(instance: unknown, obj: any): unknown;
/**
* Deserialize group of objects
* @param instance - Object instance
* @param obj - JSON data
* @returns Modified object instance
*/
deserializeGroup?(instance: unknown, obj: any): unknown;
/**
* Deserialize group member
* @param instance - Object instance
* @param obj - JSON data
* @returns Modified object instance
*/
deserializeGroupMember?(instance: unknown, obj: any): unknown;
}Usage Examples:
import { SerializerComponent, DeserializerComponent } from "typedoc";
// Custom serializer component for adding metadata
class MetadataSerializerComponent implements SerializerComponent {
serializeObject(instance: unknown, obj: any): any {
// Add custom metadata to all reflections
if (instance instanceof Reflection) {
obj.customMetadata = {
serializationTime: Date.now(),
version: "1.0.0",
customId: `custom-${instance.id}`,
};
}
return obj;
}
}
// Custom deserializer component for processing metadata
class MetadataDeserializerComponent implements DeserializerComponent {
deserializeObject(instance: unknown, obj: any): unknown {
if (obj.customMetadata && instance instanceof Reflection) {
// Process custom metadata
console.log(`Deserializing ${instance.name} from ${obj.customMetadata.serializationTime}`);
}
return instance;
}
}
// Register components
app.serializer.addComponent("metadata", new MetadataSerializerComponent());
const deserializer = new Deserializer(app);
deserializer.addComponent("metadata", new MetadataDeserializerComponent());Interface for objects that can customize their deserialization behavior.
/**
* Interface for objects that support custom deserialization
*/
interface Deserializable {
/**
* Custom deserialization logic
* @param de - Deserializer instance
* @param obj - JSON object data
*/
fromObject(de: Deserializer, obj: any): void;
}Complete schema definitions for TypeDoc's JSON output format.
namespace JSONOutput {
/**
* Base JSON reflection interface
*/
interface Reflection {
/** Reflection ID */
id: number;
/** Reflection name */
name: string;
/** Reflection kind */
kind: ReflectionKind;
/** Reflection flags */
flags: ReflectionFlag;
/** Comment data */
comment?: Comment;
/** Source references */
sources?: SourceReference[];
/** Groups */
groups?: ReflectionGroup[];
/** Categories */
categories?: ReflectionCategory[];
}
/**
* JSON project reflection
*/
interface ProjectReflection extends Reflection {
/** Package version */
packageVersion?: string;
/** README content */
readme?: string;
/** Changelog content */
changelog?: string;
/** Child reflections */
children?: DeclarationReflection[];
/** Groups organizing children */
groups?: ReflectionGroup[];
/** Categories organizing children */
categories?: ReflectionCategory[];
/** Symbol ID mappings */
symbolIdMap?: Record<string, number>;
}
/**
* JSON declaration reflection
*/
interface DeclarationReflection extends Reflection {
/** Type information */
type?: SomeType;
/** Default value */
defaultValue?: string;
/** Overwrites information */
overwrites?: ReferenceType;
/** Inherited from information */
inheritedFrom?: ReferenceType;
/** Implementation information */
implementationOf?: ReferenceType;
/** Extended types */
extendedTypes?: SomeType[];
/** Extended by types */
extendedBy?: ReferenceType[];
/** Implemented types */
implementedTypes?: SomeType[];
/** Implemented by types */
implementedBy?: ReferenceType[];
/** Type parameters */
typeParameters?: TypeParameterReflection[];
/** Signatures */
signatures?: SignatureReflection[];
/** Index signature */
indexSignature?: SignatureReflection;
/** Get signature */
getSignature?: SignatureReflection;
/** Set signature */
setSignature?: SignatureReflection;
/** Child reflections */
children?: DeclarationReflection[];
/** Variant information */
variant?: ReflectionVariant;
}
/**
* JSON signature reflection
*/
interface SignatureReflection extends Reflection {
/** Parameters */
parameters?: ParameterReflection[];
/** Return type */
type?: SomeType;
/** Type parameters */
typeParameters?: TypeParameterReflection[];
/** Overwrites information */
overwrites?: ReferenceType;
/** Inherited from information */
inheritedFrom?: ReferenceType;
/** Implementation information */
implementationOf?: ReferenceType;
}
/**
* JSON parameter reflection
*/
interface ParameterReflection extends Reflection {
/** Parameter type */
type?: SomeType;
/** Default value */
defaultValue?: string;
/** Rest parameter flag */
rest?: boolean;
/** Optional parameter flag */
optional?: boolean;
}
/**
* JSON type parameter reflection
*/
interface TypeParameterReflection extends Reflection {
/** Type constraint */
type?: SomeType;
/** Default type */
default?: SomeType;
/** Constraint type */
constraint?: SomeType;
}
}namespace JSONOutput {
/**
* Union of all possible JSON type representations
*/
type SomeType =
| ArrayType
| ConditionalType
| IndexedAccessType
| InferredType
| IntersectionType
| IntrinsicType
| LiteralType
| MappedType
| NamedTupleMemberType
| OptionalType
| PredicateType
| QueryType
| ReferenceType
| ReflectionType
| RestType
| TemplateStringType
| TupleType
| TypeOperatorType
| UnionType
| UnknownType;
/**
* JSON intrinsic type
*/
interface IntrinsicType {
type: "intrinsic";
name: string;
}
/**
* JSON literal type
*/
interface LiteralType {
type: "literal";
value?: string | number | boolean | null | bigint;
}
/**
* JSON reference type
*/
interface ReferenceType {
type: "reference";
/** Reference target name */
name: string;
/** Type arguments */
typeArguments?: SomeType[];
/** Referenced reflection ID */
target?: number;
/** External package */
package?: string;
/** Qualified name */
qualifiedName?: string;
}
/**
* JSON array type
*/
interface ArrayType {
type: "array";
/** Element type */
elementType: SomeType;
}
/**
* JSON union type
*/
interface UnionType {
type: "union";
/** Union member types */
types: SomeType[];
}
/**
* JSON intersection type
*/
interface IntersectionType {
type: "intersection";
/** Intersection member types */
types: SomeType[];
}
/**
* JSON conditional type
*/
interface ConditionalType {
type: "conditional";
/** Check type */
checkType: SomeType;
/** Extends type */
extendsType: SomeType;
/** True type */
trueType: SomeType;
/** False type */
falseType: SomeType;
}
/**
* JSON tuple type
*/
interface TupleType {
type: "tuple";
/** Tuple element types */
elements: SomeType[];
}
/**
* JSON mapped type
*/
interface MappedType {
type: "mapped";
/** Parameter name */
parameter: string;
/** Parameter type */
parameterType: SomeType;
/** Template type */
templateType: SomeType;
/** Readonly modifier */
readonlyModifier?: "+" | "-";
/** Optional modifier */
optionalModifier?: "+" | "-";
/** Name type */
nameType?: SomeType;
}
/**
* JSON template literal type
*/
interface TemplateStringType {
type: "templateString";
/** Template head */
head: string;
/** Template tail parts */
tail: [SomeType, string][];
}
}namespace JSONOutput {
/**
* JSON comment representation
*/
interface Comment {
/** Summary parts */
summary: CommentDisplayPart[];
/** Block tags */
blockTags?: CommentTag[];
/** Modifier tags */
modifierTags?: string[];
}
/**
* JSON comment display part
*/
interface CommentDisplayPart {
/** Part kind */
kind: string;
/** Text content */
text: string;
/** Link target */
target?: number | string;
}
/**
* JSON comment tag
*/
interface CommentTag {
/** Tag name */
tag: string;
/** Tag content */
content: CommentDisplayPart[];
/** Parameter name for @param tags */
name?: string;
}
/**
* JSON source reference
*/
interface SourceReference {
/** File name */
fileName: string;
/** Line number */
line: number;
/** Character position */
character: number;
/** Source URL */
url?: string;
}
/**
* JSON reflection group
*/
interface ReflectionGroup {
/** Group title */
title: string;
/** Child reflection IDs */
children: number[];
/** Categories */
categories?: ReflectionCategory[];
}
/**
* JSON reflection category
*/
interface ReflectionCategory {
/** Category title */
title: string;
/** Child reflection IDs */
children: number[];
}
}import { Serializer, JSONOutput } from "typedoc";
// Custom JSON post-processing
function processJsonOutput(jsonProject: JSONOutput.ProjectReflection): JSONOutput.ProjectReflection {
// Add custom metadata
const processed = {
...jsonProject,
metadata: {
generatedAt: new Date().toISOString(),
version: "1.0.0",
processingFlags: ["minified", "optimized"],
},
};
// Process all children recursively
if (processed.children) {
processed.children = processed.children.map(child => ({
...child,
processedAt: Date.now(),
}));
}
return processed;
}
const project = await app.convert();
if (project) {
let jsonProject = app.serializer.projectToObject(project, "docs");
jsonProject = processJsonOutput(jsonProject);
await writeFile("docs/processed-api.json", JSON.stringify(jsonProject, null, 2));
}import { Serializer } from "typedoc";
import { createWriteStream } from "fs";
// Stream large JSON output
async function streamSerializeProject(project: ProjectReflection, outputPath: string) {
const stream = createWriteStream(outputPath);
const serializer = app.serializer;
stream.write('{"project":');
// Serialize in chunks
const jsonProject = serializer.projectToObject(project, path.dirname(outputPath));
stream.write(JSON.stringify(jsonProject));
stream.write('}');
stream.end();
return new Promise<void>((resolve, reject) => {
stream.on('finish', resolve);
stream.on('error', reject);
});
}The serialization system handles various error conditions:
All serialization errors include context about the failing object and operation for debugging.
Install with Tessl CLI
npx tessl i tessl/npm-typedoc