Generic типы (обобщённые типы) позволяют создавать универсальные компоненты и функции, которые могут работать с различными типами данных без потери типизации. В контексте использования MDX вместе с TypeScript или JavaScript с типами, это становится особенно полезным при разработке компонентной системы документации или динамических интерфейсов.
Generic типы обозначаются через угловые скобки <>
после имени функции, класса или интерфейса. Например:
function identity(value: T): T {
return value;
}
Здесь T — это обобщённый параметр типа,
который позволяет функции identity принимать и возвращать
значение любого типа, сохраняя строгую типизацию.
T можно назвать любым другим идентификатором.T определяется автоматически при вызове функции,
либо задаётся явно.Пример использования:
const numberResult = identity(42);
const stringResult = identity('MDX');
MDX позволяет интегрировать JSX-компоненты прямо в Markdown. Generic компоненты особенно полезны, когда требуется компонент, который может работать с различными типами контента.
Пример универсального компонента:
interface CardProps {
title: string;
content: T;
}
function Card({ title, content }: CardProps) {
return (
{title}
{JSON.stringify(content)}
);
}
Использование:
Ключевой момент: Generic позволяет использовать один компонент для объектов, массивов и других структур данных без дублирования кода.
Иногда требуется, чтобы Generic тип удовлетворял определённым
условиям. Для этого используется extends:
function logLength(item: T): void {
console.log(item.length);
}
Примеры вызова:
logLength([1, 2, 3]); // массив
logLength("MDX"); // строка
Попытка передать число вызовет ошибку компиляции, так как у числа нет
свойства length.
Функции и компоненты могут использовать более одного Generic типа:
function merge(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
const merged = merge({ name: "MDX" }, { version: 2 });
В этом примере результат объединяет свойства обоих объектов, сохраняя типовую информацию.
В связке с 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: хук может хранить состояние любого типа, от чисел до объектов или массивов.
TypeScript способен автоматически выводить тип Generic, если он очевиден из контекста:
const result = identity(123); // TypeScript понимает, что T = number
В случае MDX-компонентов это особенно важно, когда контент динамический, а типы сложные.
interface TableProps {
data: T[];
renderRow: (item: T) => JSX.Element;
}
function Table({ data, renderRow }: TableProps) {
return {data.map(renderRow)}
;
}
interface FormProps {
initialValues: T;
onSubmit: (values: T) => void;
}
function Form({ initialValues, onSubmit }: FormProps) {
const [values, setValues] = React.useState(initialValues);
return (
);
}
Generic типы позволяют писать компоненты
Example, которые демонстрируют различные структуры
данных с полной типовой безопасностью.