A simple parser for React properties defined in TypeScript instead of propTypes
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive documentation structures for React components, including props, methods, and metadata extracted from TypeScript definitions.
The main documentation object returned for each React component.
/**
* Complete documentation for a React component
*/
interface ComponentDoc {
/** TypeScript symbol reference (when shouldIncludeExpression is true) */
expression?: ts.Symbol;
/** Root TypeScript symbol reference (when shouldIncludeExpression is true) */
rootExpression?: ts.Symbol;
/** Component display name */
displayName: string;
/** Path to the component source file */
filePath: string;
/** Component description from JSDoc comments */
description: string;
/** Component props documentation */
props: Props;
/** Component methods documentation */
methods: Method[];
/** JSDoc tags as key-value pairs */
tags?: StringIndexedObject<string>;
}Usage Examples:
import { parse } from "react-docgen-typescript";
const [componentDoc] = parse("./src/Button.tsx");
console.log(componentDoc.displayName); // "Button"
console.log(componentDoc.description); // "A reusable button component"
console.log(componentDoc.filePath); // "./src/Button.tsx"
console.log(Object.keys(componentDoc.props)); // ["variant", "size", "onClick", ...]Documentation for component properties and their types.
/**
* String-indexed object containing PropItem entries
*/
interface Props extends StringIndexedObject<PropItem> {}
/**
* Documentation for a single component property
*/
interface PropItem {
/** Property name */
name: string;
/** Whether the property is required */
required: boolean;
/** Property type information */
type: PropItemType;
/** Property description from JSDoc comments */
description: string;
/** Default value if specified */
defaultValue: any;
/** Parent interface/type information */
parent?: ParentType;
/** Type declaration locations */
declarations?: ParentType[];
/** JSDoc tags for this property */
tags?: {};
}
/**
* Type information for a property
*/
interface PropItemType {
/** Type name (string representation) */
name: string;
/** Type value for enums/unions */
value?: any;
/** Raw TypeScript type string */
raw?: string;
}Usage Examples:
import { parse } from "react-docgen-typescript";
const [componentDoc] = parse("./src/Button.tsx");
// Access prop information
const variantProp = componentDoc.props.variant;
console.log(variantProp.name); // "variant"
console.log(variantProp.required); // false
console.log(variantProp.type.name); // "primary" | "secondary" | "danger"
console.log(variantProp.description); // "Button style variant"
console.log(variantProp.defaultValue); // { value: "primary" }
// Enumerate all props
Object.entries(componentDoc.props).forEach(([propName, propInfo]) => {
console.log(`${propName}: ${propInfo.type.name} (required: ${propInfo.required})`);
});Documentation for component methods (class components and ref-exposed methods).
/**
* Method documentation for class components
*/
interface Method {
/** Method name */
name: string;
/** Full JSDoc comment block */
docblock: string;
/** Method modifiers (static, etc.) */
modifiers: string[];
/** Method parameters */
params: MethodParameter[];
/** Return type information */
returns?: {
description?: string | null;
type?: string;
} | null;
/** Method description from JSDoc */
description: string;
}
/**
* Method parameter information
*/
interface MethodParameter {
/** Parameter name */
name: string;
/** Parameter description from JSDoc */
description?: string | null;
/** Parameter type */
type: MethodParameterType;
}
/**
* Method parameter type information
*/
interface MethodParameterType {
/** Type name */
name: string;
}Usage Examples:
import { parse } from "react-docgen-typescript";
// Parse a class component with methods
const [componentDoc] = parse("./src/Modal.tsx");
// Access method information
componentDoc.methods.forEach(method => {
console.log(`Method: ${method.name}`);
console.log(`Description: ${method.description}`);
console.log(`Modifiers: ${method.modifiers.join(', ')}`);
method.params.forEach(param => {
console.log(` Param: ${param.name} (${param.type.name})`);
});
if (method.returns) {
console.log(` Returns: ${method.returns.type}`);
}
});Supporting type definitions for component documentation.
/**
* Parent type information for props
*/
interface ParentType {
/** Parent type/interface name */
name: string;
/** File path containing the type definition */
fileName: string;
}
/**
* Component identifier interface
*/
interface Component {
/** Component name */
name: string;
}
/**
* Generic string-indexed object type
*/
interface StringIndexedObject<T> {
[key: string]: T;
}When shouldExtractValuesFromUnion is enabled, union types are converted to enum format:
// TypeScript definition
type ButtonVariant = "primary" | "secondary" | "danger";
// Resulting PropItemType
{
name: "enum",
raw: "\"primary\" | \"secondary\" | \"danger\"",
value: [
{ value: "\"primary\"" },
{ value: "\"secondary\"" },
{ value: "\"danger\"" }
]
}When shouldExtractLiteralValuesFromEnum is enabled, string enums are extracted:
// TypeScript definition
enum Size {
Small = "sm",
Medium = "md",
Large = "lg"
}
// Resulting PropItemType
{
name: "enum",
raw: "Size",
value: [
{ value: "\"sm\"" },
{ value: "\"md\"" },
{ value: "\"lg\"" }
]
}Default values are captured from various sources:
// From defaultProps
Component.defaultProps = {
variant: "primary",
size: "medium"
};
// From JSDoc @default tag
/**
* @param variant Button variant
* @default "primary"
*/
// From destructuring defaults
const MyComponent = ({ variant = "primary" }) => { ... };Component documentation extraction handles various edge cases:
Install with Tessl CLI
npx tessl i tessl/npm-react-docgen-typescript