В библиотеке MUI (Material-UI) типизация компонентов играет ключевую роль при использовании TypeScript. Она обеспечивает строгий контроль над пропсами компонентов, предотвращает ошибки во время компиляции и повышает удобство автодополнения в редакторах кода.
Каждый компонент MUI является React-компонентом с заранее
определёнными типами пропсов. Например, компонент
Button имеет собственный интерфейс пропсов
ButtonProps:
import Button, { ButtonProps } from '@mui/material/Button';
const MyButton: React.FC<ButtonProps> = (props) => <Button {...props} />;
onClick, className, style) и
специфичные для MUI (variant, color,
size).<Button color="pink" /> // Ошибка: тип "pink" не входит в Color
MUI компоненты обычно расширяют стандартные HTML-элементы. Например:
Button → расширяет
ButtonHTMLAttributes<HTMLButtonElement>TextField → расширяет
InputHTMLAttributes<HTMLInputElement>Это позволяет использовать стандартные пропсы HTML вместе с MUI-специфичными:
<TextField
placeholder="Введите текст"
required
variant="outlined"
color="primary"
/>
component
prop)Многие компоненты MUI поддерживают проп component,
который позволяет изменять базовый HTML-элемент:
import { Button } from '@mui/material';
<Button component="a" href="/home" variant="contained">
Ссылка-кнопка
</Button>
Типизация здесь корректно учитывает HTML-атрибуты нового элемента
(href для <a> вместо
onClick для <button>).
Для пользовательских компонентов можно передавать свои типы:
interface LinkProps {
to: string;
}
const MyLink: React.FC<LinkProps> = ({ to, children }) => <a href={to}>{children}</a>;
<Button component={MyLink} to="/dashboard">
На дашборд
</Button>
MUI автоматически выводит правильные пропсы для MyLink
благодаря дженерикам.
Многие компоненты MUI используют TypeScript
дженерики, чтобы обеспечить строгую типизацию в зависимости от
варианта компонента или типа элемента. Пример: TextField с
кастомным InputProps:
import TextField, { TextFieldProps } from '@mui/material/TextField';
interface CustomInputProps {
maxLength: number;
}
const fieldProps: TextFieldProps<CustomInputProps> = {
InputProps: {
maxLength: 10
},
variant: 'outlined'
};
Дженерики позволяют:
InputProps, SelectProps и др.)MUI предлагает несколько способов стилизации компонентов, каждый из которых имеет собственную типизацию.
a) sx prop
SxProps поддерживает объекты с заранее определёнными
CSS-свойствами:
<Box sx={{ color: 'primary.main', p: 2, borderRadius: 1 }}>
Контент
</Box>
Типизация обеспечивает:
primary.main,
secondary.light)fontWeight,
margin, display)b) styled API
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';
const MyStyledButton = styled(Button)<{ rounded: boolean }>(
({ theme, rounded }) => ({
borderRadius: rounded ? theme.spacing(2) : theme.shape.borderRadius,
padding: theme.spacing(1, 3),
})
);
<{ rounded: boolean }> – определяет кастомный
проп, типизированный TypeScript.theme автоматически типизирован и предоставляет все
значения темы (palette, spacing,
typography).c) makeStyles и useStyles
(legacy)
import { makeStyles } from '@mui/styles';
const useStyles = makeStyles((theme) => ({
root: {
backgroundColor: theme.palette.primary.main,
},
}));
С TypeScript нужно явно типизировать theme, чтобы
избежать ошибок при доступе к палитре или типографике.
Для создания обёрток над MUI компонентами важно использовать правильные дженерики:
import { Button, ButtonProps } from '@mui/material';
interface ExtraProps {
loading: boolean;
}
const LoadingButton: React.FC<ButtonProps & ExtraProps> = ({ loading, ...props }) => (
<Button {...props} disabled={loading}>
{loading ? 'Загрузка...' : props.children}
</Button>
);
& позволяет сохранять
все стандартные пропсы MUI.loading) строго проверяются
TypeScript.ButtonProps, TextFieldProps).component, InputProps,
SelectProps).& или
extends.sx или
styled для строгой типизации CSS и темы.Типизация компонентов MUI позволяет писать предсказуемый, безопасный и автодополняемый код, что особенно важно в больших проектах на TypeScript. Она охватывает все аспекты: от стандартных HTML-пропсов до сложных кастомных компонентов с темой и стилями.