Типизация пропсов
Базовый пример
type ButtonProps = {
label: string;
onClick: () => void;
};
function Button({ label, onClick }: ButtonProps) {
return <button onClick={onClick}>{label}</button>;
}
Inline тип
function Greeting({ name }: { name: string }) {
return <p>Привет, {name}</p>;
}
Работает, но при росте компонента тип лучше выносить.
interface vs type
// type
type ButtonProps = {
label: string;
};
// interface
interface ButtonProps {
label: string;
}
Оба работают. В React чаще используют type — гибче.
Опциональные пропсы
type ButtonProps = {
label: string;
variant?: 'primary' | 'secondary';
disabled?: boolean;
};
Значения по умолчанию
function Button({ variant = 'primary', disabled = false }: ButtonProps) {
// ...
}
Или через дефолтный параметр:
function Button({ variant = 'primary' }: ButtonProps) {}
Дети (children)
import type { ReactNode } from 'react';
type CardProps = {
title: string;
children: ReactNode;
};
function Card({ title, children }: CardProps) {
return (
<div>
<h2>{title}</h2>
{children}
</div>
);
}
ReactNode — самый гибкий тип для детей: строка, JSX, массив, null.
Другие варианты:
ReactNode— всё что угодноReactElement— только JSX-элементJSX.Element— то же самоеstring | JSX.Element— строка или элемент
PropsWithChildren
import type { PropsWithChildren } from 'react';
type CardProps = PropsWithChildren<{
title: string;
}>;
function Card({ title, children }: CardProps) {}
PropsWithChildren<T> добавляет children?: ReactNode.
Функции как пропсы
type ButtonProps = {
onClick: () => void;
onDelete: (id: number) => void;
onSubmit: (data: FormData) => Promise<void>;
};
Массивы и объекты
type ListProps = {
items: string[];
config: { sort: 'asc' | 'desc' };
users: User[];
};
Union пропсов
type Props =
| { variant: 'text'; children: string }
| { variant: 'icon'; icon: ReactNode }
| { variant: 'link'; href: string; children: string };
function Button(props: Props) {
if (props.variant === 'text') return <button>{props.children}</button>;
if (props.variant === 'icon') return <button>{props.icon}</button>;
return <a href={props.href}>{props.children}</a>;
}
Каждый вариант — точный набор пропсов.
Дефолтные значения
Для компонента с optional-пропсами:
function Alert({ type = 'info', message }: AlertProps) {}
Экспорт типа
export type ButtonProps = {
label: string;
};
export function Button({ label }: ButtonProps) {}
Тип можно импортировать в других файлах.
Итоги
typeилиinterfaceдля пропсовchildren: ReactNodeдля детейPropsWithChildren<T>сокращает- Union для вариантов
- Экспортируй тип, если нужен снаружи