Типы и интерфейсы

MDX сочетает в себе возможности Markdown и JSX, предоставляя гибкую платформу для создания контента с динамическими компонентами. При работе с MDX важно понимать, как TypeScript и типизация JavaScript взаимодействуют с MDX, чтобы обеспечить корректность и предсказуемость поведения компонентов.


Определение типов контента

MDX-файлы могут содержать как обычный Markdown, так и JSX-компоненты. Основные типы данных:

  • Текстовые узлы: строки, которые интерпретируются как Markdown.
  • Элементы JSX: любые React-компоненты, встроенные в MDX.
  • Пользовательские свойства: props, передаваемые компонентам внутри MDX.

Для корректной работы с TypeScript в проекте рекомендуется использовать тип MDXContent, который экспортируется из пакета @mdx-js/react или @mdx-js/mdx. Пример типизации:

import { MDXContent } from 'mdx/types';

const Content: MDXContent = ({ components }) => (
  <div>
    <h1>Пример MDX контента</h1>
  </div>
);

Интерфейсы для компонентов MDX

Компоненты в MDX могут получать набор стандартных и пользовательских props. Основной интерфейс описывается следующим образом:

import { MDXProviderComponents } from '@mdx-js/react';

interface CustomComponents extends MDXProviderComponents {
  MyButton?: React.FC<{ label: string; onClick: () => void }>;
  Highlight?: React.FC<{ color?: string }>;
}
  • MDXProviderComponents — базовый интерфейс, включающий стандартные HTML-элементы (h1, p, ul, li, a и т.д.).
  • Любой пользовательский компонент можно добавить через расширение интерфейса.

Передача и использование props

MDX позволяет передавать props напрямую в компоненты. С помощью TypeScript можно строго типизировать эти props:

type AlertProps = {
  type: 'success' | 'error';
  message: string;
};

const Alert: React.FC<AlertProps> = ({ type, message }) => (
  <div className={`alert alert-${type}`}>{message}</div>
);

В MDX:

<Alert type="success" message="Операция выполнена успешно" />

TypeScript обеспечит проверку допустимых значений type и обязательного наличия message.


Типы для frontmatter

MDX поддерживает frontmatter в формате YAML. Для работы с ним также полезна типизация:

interface Frontmatter {
  title: string;
  date: string;
  tags?: string[];
}

const metadata: Frontmatter = {
  title: 'Пример MDX',
  date: '2026-03-23',
  tags: ['typescript', 'mdx', 'react']
};

Использование строгих интерфейсов предотвращает ошибки при извлечении данных из frontmatter и позволяет интегрировать его с системами рендеринга статических страниц.


Типизация MDXProvider

MDXProvider позволяет переопределять стандартные HTML-элементы в MDX. Типизация компонентов гарантирует безопасность при передаче props:

import { MDXProvider } from '@mdx-js/react';

const components: CustomComponents = {
  h1: (props) => <h1 style={{ color: 'blue' }} {...props} />,
  MyButton: ({ label, onClick }) => <button onCl ick={onClick}>{label}</button>
};

<MDXProvider components={components}>
  <Content />
</MDXProvider>

Преимущество такой типизации заключается в том, что ошибки в структуре компонентов будут выявлены на этапе компиляции.


Типы для динамических импортов MDX

MDX-файлы часто импортируются динамически. Чтобы корректно работать с ними в TypeScript, создаются декларации модулей:

declare module '*.mdx' {
  import { MDXComponent } from '@mdx-js/react';
  const content: MDXComponent;
  export default content;
}

Это позволяет писать:

import Page from './page.mdx';

<Page />

И получать поддержку автодополнения и проверку типов для передаваемых props.


Универсальные интерфейсы для контента

Для сложных проектов удобно создавать универсальные интерфейсы для всех MDX-файлов:

interface MDXPage<Props = {}> {
  default: React.FC<Props>;
  frontmatter: Frontmatter;
}

Такой подход позволяет:

  • Извлекать frontmatter без лишних кастов.
  • Писать единый тип для всех страниц.
  • Использовать строгую типизацию в рендерерах и маршрутизаторах.

Выводы по типам и интерфейсам

  • Строгая типизация MDX-контента снижает риск ошибок при передаче props.
  • Использование интерфейсов упрощает работу с пользовательскими компонентами и frontmatter.
  • Обеспечивает удобство интеграции с React и TypeScript в крупных проектах.
  • Позволяет создавать динамические, безопасные и предсказуемые MDX-страницы с автодополнением и проверкой типов на этапе компиляции.

Типы и интерфейсы являются ключевым инструментом при работе с MDX, особенно в профессиональных проектах с большим количеством контента и компонентов.