MUI Docs Infra

Abstract Create Types

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.

Overview

Type factories created with abstractCreateTypes automatically integrate with:

Factory Function Requirements

At 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</> };
};

Implementation

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,
});

Customizing Type Rendering

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.

Loader Configuration

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.

Advanced: Custom HOC Logic

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

Custom Factory with TypeScript Generics

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:

  • Type-safe factory calls without runtime component arguments
  • Cleaner syntax when components are only used for type extraction
  • Custom options objects as the second parameter

The loadPrecomputedTypesMeta loader supports this pattern and will extract type information from the generic parameter.

Types

abstractCreateTypes

No types to display

See Types

createTypesFactory

No types to display

See Types

createMultipleTypesFactory

No types to display

See Types

Related