Типизация props

MDX сочетает возможности Markdown и JSX, позволяя внедрять компоненты React прямо в документацию. Для корректной работы с компонентами и предотвращения ошибок на этапе компиляции важно правильно типизировать их props. Типизация обеспечивает:

  • Предсказуемое поведение компонентов
  • Своевременную проверку корректности данных
  • Автодополнение в редакторах кода

Основы типизации props

В MDX компоненты обычно импортируются из JavaScript или TypeScript-файлов и используются как JSX. Рассмотрим базовый пример:

import { Button } from './Button';

<Button label="Отправить" disabled={false} />

Если проект использует TypeScript, следует описать интерфейс props:

interface ButtonProps {
  label: string;
  disabled?: boolean;
}

Компонент можно объявить так:

const Button: React.FC<ButtonProps> = ({ label, disabled = false }) => {
  return <button disabled={disabled}>{label}</button>;
};

Использование TypeScript с MDX позволяет автоматически проверять соответствие переданных props интерфейсу, предотвращая ошибки во время сборки.

Типизация компонентов, используемых в MDX

MDX не ограничивает использование типов, применяемых в обычных React-компонентах. Для интеграции с TypeScript:

  1. Создать отдельный файл для компонента с типами (Button.tsx).
  2. Импортировать компонент в .mdx файл.
  3. Использовать компонент с корректными props.

Пример MDX-файла:

import { Button } from './Button';

<Button label="Сохранить" disabled={true} />

TypeScript проверит, что label — строка, а disabled — логическое значение. Если передать label={123}, компилятор выдаст ошибку.

Использование Generics для универсальных компонентов

Иногда требуется создавать универсальные компоненты, работающие с разными типами данных:

interface SelectProps<T> {
  options: T[];
  onSelect: (value: T) => void;
}

function Select<T>({ options, onSelect }: SelectProps<T>) {
  return (
    <sel ect onCha nge={e => onSelect(options[Number(e.target.value)])}>
      {options.map((option, index) => (
        <option key={index} value={index}>{String(option)}</option>
      ))}
    </select>
  );
}

В MDX компонент можно использовать с конкретными типами:

<Select<number> 
  options={[1, 2, 3]} 
  onSel ect={value => console.log(value)} 
/>

TypeScript гарантирует соответствие типов и корректность вызова onSelect.

DefaultProps и обязательность props

Для MDX-компонентов можно указывать значения по умолчанию через defaultProps или через деструктуризацию:

interface CardProps {
  title: string;
  visible?: boolean;
}

const Card: React.FC<CardProps> = ({ title, visible = true }) => {
  if (!visible) return null;
  return <div>{title}</div>;
};

Это обеспечивает гибкость: некоторые props могут быть необязательными, при этом типизация сохраняется строгой.

Расширение типов для MDX-контента

MDX позволяет внедрять компоненты с произвольными props, но иногда полезно расширять стандартные типы MDXProps. Это особенно важно при создании документации или интерактивных гайдов:

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

interface CustomComponents extends MDXProviderComponents {
  Alert: React.FC<{ type: 'error' | 'info'; message: string }>;
}

const components: CustomComponents = {
  Alert: ({ type, message }) => <div className={`alert ${type}`}>{message}</div>,
};

Использование такого подхода обеспечивает строгую типизацию и автодополнение для всех кастомных компонентов MDX.

Практика: комбинирование Markdown и JSX с типами

MDX позволяет смешивать текст и компоненты, что делает важной строгую типизацию props:

import { Alert } from './Alert';

# Важная информация

<Alert type="error" message="Произошла ошибка при загрузке данных" />

Если указать type="warning", TypeScript сообщит об ошибке, так как допустимы только 'error' или 'info'.

Советы по типизации MDX-компонентов

  • Использовать TypeScript для всех компонентов, импортируемых в MDX.
  • Описывать интерфейсы или типы Props для всех компонентов.
  • Применять Generics для компонентов, работающих с разными типами данных.
  • Указывать значения по умолчанию для необязательных props.
  • Расширять MDXProviderComponents при необходимости кастомных компонентов.

Эти практики позволяют создавать безопасные, предсказуемые и удобные для поддержки MDX-документы с полноценной типизацией.