The abstractCreateTypes function helps you create structured type documentation factories that work seamlessly with the loadPrecomputedTypesMeta loader. It provides a standardized way to create type documentation components that display TypeScript type information extracted at build time.
Tip
For the underlying architectural rationale (URLs as identity, variant enumeration, precompute) see the Built Factories Pattern.
Type factories created with abstractCreateTypes automatically integrate with:
loadPrecomputedTypesMeta: For build-time type extractionuseTypes: For converting HAST types to React nodesAt the fundamental level, the loadPrecomputedTypesMeta function expects factory functions with these signatures:
// Single component types
export const createTypes = (url: string, component: any, options?: any) => {
return () => <>Type Documentation</>;
};
// Multi-component types (e.g., Checkbox.Root, Checkbox.Indicator)
export const createMultipleTypes = (url: string, components: Record<string, any>, options?: any) => {
return { [key: string]: () => <>Type Documentation</> };
};
To quickly implement these factory functions, use the abstractCreateTypes utilities:
import 'server-only'; // Omit if factories will be imported in client components or Pages Router
import {
createTypesFactory,
createMultipleTypesFactory,
} from '@mui/internal-docs-infra/abstractCreateTypes';
import { TypesContent } from './TypesContent';
import { Pre } from './Pre';
const components = { pre: Pre };
/**
* Creates a type documentation component for a single component.
* @param url Depends on `import.meta.url` to determine the source file location.
* @param component The component to extract types from.
* @param meta Additional metadata for the types (injected by loader).
*/
export const createTypes = createTypesFactory({
TypesContent,
// Optional: Customize how types are rendered
components,
});
/**
* Creates type documentation components for multiple related components.
* Useful for component families like Checkbox.Root, Checkbox.Indicator.
* @param url Depends on `import.meta.url` to determine the source file location.
* @param components Object with multiple component exports.
* @param meta Additional metadata for the types (injected by loader).
*/
export const createMultipleTypes = createMultipleTypesFactory({
TypesContent,
// Optional: Customize how types are rendered
components,
});
The components option allows you to customize how type information is rendered:
export const createTypes = createTypesFactory({
TypesContent,
components: {
// Custom component for rendering code blocks in type signatures
pre: ({ children, ...props }) => (
<pre className="custom-type-code" {...props}>
{children}
</pre>
),
},
});
You can also override components per type:
// In your types.ts file
export const TypesButton = createTypes(import.meta.url, Button, {
components: {
pre: SpecialPreComponent, // Overrides factory-level component
},
});
The components from the type-level metadata take priority over factory-level components.
To make type extraction work properly, configure the webpack loader. The easiest way is using withDocsInfra:
// next.config.js
import { withDocsInfra } from '@mui/internal-docs-infra/withDocsInfra';
export default withDocsInfra({
// withDocsInfra automatically includes:
// - './app/**/types.ts' (for type extraction)
});
For manual configuration, see the loadPrecomputedTypesMeta documentation.
Only needed when createTypesFactory or createMultipleTypesFactory don't provide enough flexibility:
import { abstractCreateTypes } from '@mui/internal-docs-infra/abstractCreateTypes';
import type { TypesTableMeta } from '@mui/internal-docs-infra/abstractCreateTypes';
import { MyTypesTable } from './MyTypesTable';
export function createMyTypes(url: string, typeDef: object, meta?: TypesTableMeta) {
// Custom logic before creating the component
const enhancedMeta = meta ? { ...meta, customFlag: true } : meta;
// Wrap abstractCreateTypes with your custom behavior
return abstractCreateTypes({ TypesContent: MyTypesTable }, url, enhancedMeta);
}
For even more flexibility, you can create a factory function from scratch that uses TypeScript generics to specify components:
import { abstractCreateTypes } from '@mui/internal-docs-infra/abstractCreateTypes';
import type { TypesTableMeta } from '@mui/internal-docs-infra/abstractCreateTypes';
import { MyTypesTable } from './MyTypesTable';
// Single component with generics
export function createTypes<TComponent>(
url: string,
options?: Record<string, any>,
meta?: TypesTableMeta,
) {
return abstractCreateTypes({ TypesContent: MyTypesTable }, url, meta);
}
// Multiple components with generics
export function createMultipleTypes<TComponents extends Record<string, any>>(
url: string,
options?: Record<string, any>,
meta?: TypesTableMeta,
): Record<keyof TComponents, React.ComponentType> {
// Implementation logic here
return {} as Record<keyof TComponents, React.ComponentType>;
}
Usage:
// In types.ts - Single component
import { Button } from './Button';
export const TypesButton = createTypes<Button>(import.meta.url);
// In types.ts - Multiple components
import { Checkbox } from './Checkbox';
const types = createMultipleTypes<typeof Checkbox>(import.meta.url);
export const TypesCheckboxRoot = types.Root;
export const TypesCheckboxIndicator = types.Indicator;
This approach allows the component types to be inferred from the generic parameter, enabling:
The loadPrecomputedTypesMeta loader supports this pattern and will extract type information from the generic parameter.
abstractCreateTypescreateTypesFactorycreateMultipleTypesFactoryimport.meta.url and filesystem-based routingloadPrecomputedTypesMeta: Build-time loader that extracts typesuseTypes: Hook for accessing processed types in TypesContent components