Chakra UI полностью совместим с TypeScript, однако при использовании
его компонентов могут возникать сложности с типами, особенно при
расширении компонентов, работе с системными пропсами или создании
собственных UI-компонентов на основе Box и
Flex.
Ключевой момент: все компоненты Chakra UI имеют строго определённые пропсы, соответствующие системе стилей и функциональности библиотеки.
Компоненты Chakra UI поддерживают системные пропсы (margin, padding,
color, fontSize и др.). В TypeScript эти пропсы строго типизированы
через интерфейсы SystemProps и
ResponsiveValue.
Пример корректного использования:
import { Box } from "@chakra-ui/react";
const StyledBox: React.FC = () => (
<Box
p={4} // padding
m={{ base: 2, md: 4 }} // responsive margin
bg="teal.500"
color="white"
>
Пример Box с системными пропсами
</Box>
);
Здесь p и m имеют тип
ResponsiveValue<string | number>, что позволяет
задавать как фиксированные значения, так и адаптивные через объект
base/md/lg.
При создании пользовательских компонентов на основе Chakra UI важно
правильно типизировать пропсы. Наиболее универсальный подход —
использовать ComponentProps или ChakraProps из
@chakra-ui/react.
import { Button, ChakraProps } from "@chakra-ui/react";
interface CustomButtonProps extends ChakraProps {
isLoading?: boolean;
}
const CustomButton: React.FC<CustomButtonProps> = ({ isLoading, ...props }) => (
<Button {...props} isLoading={isLoading}>
Кнопка
</Button>
);
Использование ChakraProps гарантирует, что все системные
пропсы будут корректно типизированы, а isLoading добавлен
как пользовательский пропс.
Некорректная работа с ref часто возникает при обёртке компонентов
Chakra. Для сохранения типизации и корректной работы ref
необходимо использовать forwardRef:
import { forwardRef } from "react";
import { Input, InputProps } from "@chakra-ui/react";
const CustomInput = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
<Input ref={ref} {...props} />
));
Использование forwardRef позволяет TypeScript понимать
тип ref и передавать его корректно в родительский
компонент.
Chakra UI позволяет расширять стандартную тему через
extendTheme. При этом TypeScript требует правильного
определения интерфейсов для новых цветов, шрифтов и размеров:
import { extendTheme, ThemeConfig, ThemeOverride } from "@chakra-ui/react";
const customTheme = extendTheme({
colors: {
brand: {
50: "#f5faff",
500: "#3182ce",
900: "#1a365d",
},
},
fonts: {
heading: "Montserrat, sans-serif",
body: "Inter, sans-serif",
},
});
type CustomTheme = typeof customTheme;
Расширение глобального theme через
declare module "@chakra-ui/react" позволяет TypeScript
корректно понимать новые свойства и предотвращает ошибки при обращении к
несуществующим ключам.
import "@chakra-ui/react";
declare module "@chakra-ui/react" {
export interface Theme {
colors: {
brand: {
50: string;
500: string;
900: string;
};
};
}
}
Компоненты вроде Box или Flex по умолчанию
уже типизированы для React children. Ошибки возникают при создании
собственных компонентов, где children могут быть обязательными или
специфическими.
Пример корректной типизации:
interface CardProps extends ChakraProps {
title: string;
children: React.ReactNode;
}
const Card: React.FC<CardProps> = ({ title, children, ...props }) => (
<Box p={4} shadow="md" borderWidth="1px" {...props}>
<Box fontWeight="bold">{title}</Box>
{children}
</Box>
);
При использовании React.lazy с Chakra UI важно сохранять
типизацию пропсов:
import { Suspense, lazy } from "react";
import { Spinner } from "@chakra-ui/react";
const LazyComponent = lazy(() => import("./SomeChakraComponent"));
const Wrapper = () => (
<Suspense fallback={<Spinner />}>
<LazyComponent p={4} />
</Suspense>
);
p={4} корректно типизируется через
ChakraProps, предотвращая ошибки при динамической загрузке
компонента.
Ошибка: Type ‘{ children: string; bg: string; }’ is not assignable to type…
ChakraProps. Решение: наследовать интерфейс от
ChakraProps или использовать
ComponentProps<typeof Box>.Ошибка при работе с ref
forwardRef с правильными дженериками
для HTML-элементов.Ошибки при расширении темы
declare module "@chakra-ui/react"
и точно типизировать новые ключи темы.Ошибки с responsive-пропсами
ResponsiveValue должен включать все используемые
типы значений:
number | string | Array<number | string> | { base?: T; sm?: T; md?: T; lg?: T; xl?: T }.Использование этих подходов обеспечивает строгую типизацию и предотвращает большинство ошибок TypeScript при работе с Chakra UI, одновременно сохраняя гибкость компонентов и поддержку системы стилей.