MDX (Markdown + JSX) представляет собой расширение стандартного Markdown, позволяющее интегрировать компоненты React напрямую в текст документации. Для эффективной работы с MDX необходима строгая типизация, особенно при использовании TypeScript. Утилитарные типы помогают создавать гибкие и безопасные структуры данных, облегчая работу с компонентами и контентом MDX.
Props
для компонентов MDXВ MDX каждый React-компонент может принимать пропсы. Для типизации этих пропсов используют встроенные утилитарные типы TypeScript:
type ComponentProps<T> = T extends React.ComponentType<infer P> ? P : never;
ComponentProps<T> извлекает тип
пропсов компонента T.Пример использования с MDX-компонентом:
import { Button } from './Button';
type ButtonProps = ComponentProps<typeof Button>;
const mdxContent: ButtonProps = {
label: "Нажми меня",
disabled: false
};
Такой подход исключает несовпадения типов между компонентом и его использованием в MDX.
PartialУтилита Partial<T> превращает все свойства типа
T в необязательные:
interface AlertProps {
message: string;
type: 'info' | 'error' | 'success';
duration: number;
}
const optionalAlert: Partial<AlertProps> = {
message: "Привет"
};
RequiredПротивоположность Partial, делает все свойства
обязательными:
interface TooltipProps {
content?: string;
position?: 'top' | 'bottom';
}
const tooltip: Required<TooltipProps> = {
content: "Информация",
position: "top"
};
PickПозволяет выбрать подмножество свойств типа:
interface CardProps {
title: string;
description: string;
image: string;
link: string;
}
type CardPreviewProps = Pick<CardProps, 'title' | 'image'>;
const preview: CardPreviewProps = {
title: "Заголовок",
image: "image.png"
};
OmitПротивоположность Pick, исключает указанные
свойства:
type CardWithoutLink = Omit<CardProps, 'link'>;
const card: CardWithoutLink = {
title: "Заголовок",
description: "Описание",
image: "image.png"
};
RecordПозволяет создавать объектные структуры с фиксированными ключами и единым типом значений:
type MDXComponents = Record<'h1' | 'p' | 'code', React.ComponentType<any>>;
const components: MDXComponents = {
h1: (props) => <h1 {...props} />,
p: (props) => <p {...props} />,
code: (props) => <pre {...props} />
};
ReadonlyДелает все свойства объекта доступными только для чтения:
interface Config {
apiUrl: string;
timeout: number;
}
const config: Readonly<Config> = {
apiUrl: "https://api.example.com",
timeout: 5000
};
// Ошибка: config.timeout = 1000;
MDX-проекты часто комбинируют утилитарные типы для сложных сценариев:
type EditableAlertProps = Partial<Omit<AlertProps, 'duration'>>;
Omit<AlertProps, 'duration'> исключает свойство
duration.Partial<...> делает оставшиеся свойства
необязательными.ReturnTypeПозволяет извлечь тип возвращаемого значения функции:
function createButton(label: string) {
return <button>{label}</button>;
}
type ButtonElement = ReturnType<typeof createButton>;
import { Meta, Story } from '@storybook/react';
import { Button } from './Button';
type ButtonStoryProps = Partial<ComponentProps<typeof Button>>;
<Meta title="Components/Button" component={Button} />
<Story name="Primary">
<Button label="Click me" />
</Story>
ComponentProps гарантирует точность типов
для пропсов.Partial позволяет задавать только необходимые параметры
для сторибука или документации.Эти утилитарные типы формируют основу безопасного и масштабируемого подхода к работе с MDX в TypeScript. Их грамотное применение позволяет создавать гибкие компоненты, типизированные конфигурации и надежные интерфейсы, минимизируя ошибки и ускоряя разработку.