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 configuration options for customizing parsing behavior, filtering properties, and controlling output format.
Main configuration interface for customizing parser behavior.
/**
* Configuration options for the parser
*/
interface ParserOptions {
/** Filter function or configuration for properties */
propFilter?: StaticPropFilter | PropFilter;
/** Custom component name resolver function */
componentNameResolver?: ComponentNameResolver;
/** Extract literal values from string enums */
shouldExtractLiteralValuesFromEnum?: boolean;
/** Remove " | undefined" from optional types display */
shouldRemoveUndefinedFromOptional?: boolean;
/** Extract all union type values as enum format */
shouldExtractValuesFromUnion?: boolean;
/** Sort union members alphabetically */
shouldSortUnions?: boolean;
/** Skip children prop when it has no documentation */
skipChildrenPropWithoutDoc?: boolean;
/** Save default prop values as strings instead of parsed values */
savePropValueAsString?: boolean;
/** Include JSDoc tag mappings in prop documentation */
shouldIncludePropTagMap?: boolean;
/** Include TypeScript expression symbols in output */
shouldIncludeExpression?: boolean;
/** Custom component type names to recognize */
customComponentTypes?: string[];
}Control which properties are included in the documentation output.
/**
* Function type for filtering properties
* @param prop - Property information
* @param component - Component information
* @returns true to include prop, false to exclude
*/
type PropFilter = (prop: PropItem, component: Component) => boolean;
/**
* Static filter configuration for properties
*/
interface StaticPropFilter {
/** Property names to skip (string or array) */
skipPropsWithName?: string[] | string;
/** Skip properties without JSDoc documentation */
skipPropsWithoutDoc?: boolean;
}Usage Examples:
import { parse } from "react-docgen-typescript";
// Static filtering
const docsWithStaticFilter = parse("./src/Button.tsx", {
propFilter: {
skipPropsWithName: ['className', 'style', 'key', 'ref'],
skipPropsWithoutDoc: true
}
});
// Function-based filtering
const docsWithFunctionFilter = parse("./src/Button.tsx", {
propFilter: (prop, component) => {
// Skip props from node_modules
if (prop.declarations?.some(decl => decl.fileName.includes('node_modules'))) {
return false;
}
// Skip HTML attributes for certain components
if (component.name === 'Button' && ['onClick', 'onFocus', 'onBlur'].includes(prop.name)) {
return false;
}
return true;
}
});Customize how component names are determined.
/**
* Function type for resolving component names
* @param exp - TypeScript symbol for the component
* @param source - Source file containing the component
* @returns Component name, or undefined/null/false to use default logic
*/
type ComponentNameResolver = (
exp: ts.Symbol,
source: ts.SourceFile
) => string | undefined | null | false;Usage Examples:
import { parse } from "react-docgen-typescript";
const docs = parse("./src/StyledButton.tsx", {
componentNameResolver: (exp, source) => {
// Handle styled-components
if (exp.getName() === "StyledComponentClass") {
return "StyledButton";
}
// Handle default exports
if (exp.getName() === "default") {
const fileName = source.fileName.split('/').pop()?.replace('.tsx', '');
return fileName;
}
// Use default logic
return undefined;
}
});Control how TypeScript types are processed and displayed.
// Extract enum literal values
shouldExtractLiteralValuesFromEnum?: boolean;
// Extract union type values
shouldExtractValuesFromUnion?: boolean;
// Sort union members
shouldSortUnions?: boolean;
// Remove undefined from optional types
shouldRemoveUndefinedFromOptional?: boolean;Usage Examples:
import { parse } from "react-docgen-typescript";
// Enhanced type extraction
const docs = parse("./src/Button.tsx", {
shouldExtractLiteralValuesFromEnum: true,
shouldExtractValuesFromUnion: true,
shouldSortUnions: true,
shouldRemoveUndefinedFromOptional: true
});
// Results in detailed enum information:
// type: { name: "enum", value: [{ value: '"danger"' }, { value: '"primary"' }, { value: '"secondary"' }] }
// instead of: { name: '"primary" | "secondary" | "danger"' }Control how default property values are captured and formatted.
// Save default values as strings
savePropValueAsString?: boolean;Usage Examples:
import { parse } from "react-docgen-typescript";
// String default values
const docsWithStringDefaults = parse("./src/Counter.tsx", {
savePropValueAsString: true
});
// Result: { defaultValue: { value: "123" } }
// Parsed default values (default behavior)
const docsWithParsedDefaults = parse("./src/Counter.tsx", {
savePropValueAsString: false
});
// Result: { defaultValue: { value: 123 } }Control additional metadata inclusion in the output.
// Include JSDoc tag mappings
shouldIncludePropTagMap?: boolean;
// Include TypeScript expressions
shouldIncludeExpression?: boolean;
// Skip children prop without docs
skipChildrenPropWithoutDoc?: boolean;Usage Examples:
import { parse } from "react-docgen-typescript";
const enhancedDocs = parse("./src/Button.tsx", {
shouldIncludePropTagMap: true,
shouldIncludeExpression: true,
skipChildrenPropWithoutDoc: false
});
// Includes additional metadata:
// - JSDoc tags in prop.tags
// - TypeScript symbols in componentDoc.expression
// - children prop even without documentationExtend component recognition beyond default React patterns.
// Custom component type names
customComponentTypes?: string[];Usage Examples:
import { parse } from "react-docgen-typescript";
const docs = parse("./src/CustomComponent.tsx", {
customComponentTypes: [
'MyCustomComponent',
'SpecialWrapper',
'ThirdPartyComponent'
]
});
// Recognizes components with these type names as valid React componentsimport { withDefaultConfig } from "react-docgen-typescript";
const parser = withDefaultConfig({
propFilter: {
skipPropsWithName: ['className', 'style'],
skipPropsWithoutDoc: true
},
componentNameResolver: (exp, source) => {
if (exp.getName() === "StyledComponentClass") {
return source.fileName.split('/').pop()?.replace('.tsx', '') || 'Component';
}
return undefined;
},
shouldExtractLiteralValuesFromEnum: true,
shouldExtractValuesFromUnion: true,
shouldSortUnions: true,
shouldRemoveUndefinedFromOptional: true,
skipChildrenPropWithoutDoc: true,
savePropValueAsString: true,
shouldIncludePropTagMap: true,
shouldIncludeExpression: false,
customComponentTypes: ['StyledComponent', 'MyCustomWrapper']
});
const docs = parser.parse("./src/components/*.tsx");/**
* Default parser options (empty object)
*/
const defaultParserOpts: ParserOptions;When no options are provided, the parser uses sensible defaults:
Install with Tessl CLI
npx tessl i tessl/npm-react-docgen-typescript