Props компонента типізують звичайним типом чи інтерфейсом у параметрі функції:
type ButtonProps = {
label: string;
variant?: 'primary' | 'secondary'; // необов'язковий
onClick: () => void;
};
function Button({ label, variant = 'primary', onClick }: ButtonProps) {
return <button className={variant} onClick={onClick}>{label}</button>;
}
Значення за замовчуванням задають деструктуризацією - окремий defaultProps для функціональних компонентів у React 19 більше не підтримується.
children оголошують явно - як і будь-який інший prop:
import type { ReactNode } from 'react';
type CardProps = {
title: string;
children: ReactNode;
};
ReactNode чи ReactElement:
ReactNode- усе, що React уміє відрендерити: JSX, рядки, числа,bigint,null,undefined,boolean, масиви цього, а також проміси (дляuse). Правильний тип дляchildrenу більшості випадків;ReactElement- лише результат JSX (<div />,<Card />). Рядок чиnullтуди не передати. Доречний, коли компонент справді приймає рівно один елемент (наприклад, щоб клонувати його чи додати props).
<Card title="Профіль">Текст</Card> // ReactNode - ок
<Tooltip content="Підказка"><button /></Tooltip> // children: ReactElement
React.JSX.Element - тип, який повертає JSX-вираз. У React 19 глобального простору імен JSX більше немає: пишуть React.JSX.Element або імпортують JSX з react. Тип повернення компонента зазвичай не вказують - TypeScript виведе його сам.
React.FC у сучасному коді вживають рідко: він не додає користі порівняно з типізованим параметром, а історично неявно додавав children. Звичайна функція з типізованими props - стандарт.
Пастка: children: JSX.Element забороняє передати текст чи кілька елементів - помилка компіляції там, де її не очікують.
Докладніше в документації: TypeScript у React: типізація children