Generic типы

Generic типы (обобщённые типы) позволяют создавать универсальные компоненты и функции, которые могут работать с различными типами данных без потери типизации. В контексте использования MDX вместе с TypeScript или JavaScript с типами, это становится особенно полезным при разработке компонентной системы документации или динамических интерфейсов.


Объявление Generic типов

Generic типы обозначаются через угловые скобки <> после имени функции, класса или интерфейса. Например:

function identity(value: T): T {
  return value;
}

Здесь T — это обобщённый параметр типа, который позволяет функции identity принимать и возвращать значение любого типа, сохраняя строгую типизацию.

  • T можно назвать любым другим идентификатором.
  • Тип T определяется автоматически при вызове функции, либо задаётся явно.

Пример использования:

const numberResult = identity(42);
const stringResult = identity('MDX');

Generic типы в компонентах MDX

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

Пример универсального компонента:

interface CardProps {
  title: string;
  content: T;
}

function Card({ title, content }: CardProps) {
  return (
    

{title}

{JSON.stringify(content)}
); }

Использование:


Ключевой момент: Generic позволяет использовать один компонент для объектов, массивов и других структур данных без дублирования кода.


Ограничения Generic типов

Иногда требуется, чтобы Generic тип удовлетворял определённым условиям. Для этого используется extends:

function logLength(item: T): void {
  console.log(item.length);
}

Примеры вызова:

logLength([1, 2, 3]); // массив
logLength("MDX"); // строка

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


Несколько Generic параметров

Функции и компоненты могут использовать более одного Generic типа:

function merge(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const merged = merge({ name: "MDX" }, { version: 2 });

В этом примере результат объединяет свойства обоих объектов, сохраняя типовую информацию.


Generic типы в хук-компонентах React с MDX

В связке с React часто используются Generic типы для хуков:

function useStateWithHistory(initialValue: T) {
  const [state, setState] = React.useState(initialValue);
  const [history, setHistory] = React.useState([initialValue]);

  const setStateWithHistory = (newValue: T) => {
    setState(newValue);
    setHistory([...history, newValue]);
  };

  return [state, setStateWithHistory, history] as const;
}

const [count, setCount, history] = useStateWithHistory(0);

Преимущество Generic: хук может хранить состояние любого типа, от чисел до объектов или массивов.


Инференс типов и Generic

TypeScript способен автоматически выводить тип Generic, если он очевиден из контекста:

const result = identity(123); // TypeScript понимает, что T = number

В случае MDX-компонентов это особенно важно, когда контент динамический, а типы сложные.


Ограничения при использовании Generic в MDX

  • MDX не поддерживает полноценные TypeScript Generic в чистом Markdown. Generic применим только в JSX-компонентах, импортируемых в MDX.
  • Generic компоненты нельзя напрямую использовать как Markdown-синтаксис; они должны быть обёрнуты в JSX-теги.
  • Типизация контента в MDX через Generic позволяет минимизировать ошибки при передаче сложных данных, таких как JSON-объекты или массивы элементов.

Практическое применение

  1. Универсальные таблицы данных:
interface TableProps {
  data: T[];
  renderRow: (item: T) => JSX.Element;
}

function Table({ data, renderRow }: TableProps) {
  return {data.map(renderRow)}
; }
  1. Универсальные формы:
interface FormProps {
  initialValues: T;
  onSubmit: (values: T) => void;
}

function Form({ initialValues, onSubmit }: FormProps) {
  const [values, setValues] = React.useState(initialValues);
  return (
    
onSubmit(values)}> {/* рендер полей */}
); }
  1. Компоненты для документации:

Generic типы позволяют писать компоненты Example, которые демонстрируют различные структуры данных с полной типовой безопасностью.


Выводы по использованию Generic

  • Generic типы повышают гибкость компонентов и функций.
  • Позволяют сохранять строгую типизацию при работе с различными структурами данных.
  • В MDX их использование ограничено компонентами JSX, но они идеально подходят для динамических интерфейсов, таблиц, форм и обобщённых UI-элементов.