Props are values passed from a parent React component to a child component. In TypeScript, props can be typed using interfaces or type aliases so that components receive the correct kind of data.
Props are data passed from a parent component to a child component.
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
}
Here, name is a prop.
TypeScript allows us to specify what data a component expects.
interface UserProps {
name: string;
}
function User(props: UserProps) {
return <h2>{props.name}</h2>;
}
The component expects a name prop of type
string.
<User name="Rahul" />
The value "Rahul" is a string, so it matches
the defined prop type.
interface StudentProps {
age: number;
}
function Student({
age
}: StudentProps) {
return <p>Age: {age}</p>;
}
The age prop must be a number.
<Student age={20} />
Curly braces are used to pass a JavaScript or TypeScript expression such as a number.
interface ButtonProps {
disabled: boolean;
}
function Button({
disabled
}: ButtonProps) {
return (
<button disabled={disabled}>
Submit
</button>
);
}
<Button disabled={true} />
Boolean values are normally passed inside curly braces.
interface StudentProps {
name: string;
age: number;
course: string;
}
function Student({
name,
age,
course
}: StudentProps) {
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Course: {course}</p>
</div>
);
}
<Student
name="Rahul"
age={20}
course="React Native"
/>
All required props must be supplied.
A prop is required when it does not have the
? symbol.
interface UserProps {
name: string;
email: string;
}
Both name and email are required.
Add ? after a property name to make the prop
optional.
interface UserProps {
name: string;
email?: string;
}
The component can be used without providing
email.
interface UserProps {
name: string;
age?: number;
}
function User({
name,
age = 18
}: UserProps) {
return (
<p>
{name} - {age}
</p>
);
}
A type alias can also be used to define component props.
type UserProps = {
name: string;
age: number;
};
function User({
name,
age
}: UserProps) {
return (
<h2>
{name} - {age}
</h2>
);
}
interface Student {
id: number;
name: string;
course: string;
}
interface StudentProps {
student: Student;
}
function StudentCard({
student
}: StudentProps) {
return (
<div>
<h2>{student.name}</h2>
<p>ID: {student.id}</p>
<p>Course: {student.course}</p>
</div>
);
}
const student = {
id: 101,
name: "Rahul",
course: "TypeScript"
};
<StudentCard student={student} />
The object must match the Student type.
interface StudentListProps {
students: string[];
}
function StudentList({
students
}: StudentListProps) {
return (
<ul>
{students.map((student) =>
<li key={student}>
{student}
</li>
)}
</ul>
);
}
interface Student {
id: number;
name: string;
}
interface StudentListProps {
students: Student[];
}
function StudentList({
students
}: StudentListProps) {
return (
<div>
{students.map((student) => (
<p key={student.id}>
{student.name}
</p>
))}
</div>
);
}
Functions can be passed as props to allow a child component to trigger an action in the parent.
interface ButtonProps {
onClick: () => void;
}
function Button({
onClick
}: ButtonProps) {
return (
<button onClick={onClick}>
Click
</button>
);
}
interface UserProps {
onSelect: (id: number) => void;
}
function UserButton({
onSelect
}: UserProps) {
return (
<button
onClick={() => onSelect(101)}
>
Select User
</button>
);
}
ReactNode can be used when a component needs
to accept React content such as text or JSX.
import { ReactNode } from "react";
interface CardProps {
children: ReactNode;
}
function Card({
children
}: CardProps) {
return (
<div>
{children}
</div>
);
}
<Card>
<h2>Student Details</h2>
<p>Welcome to React.</p>
</Card>
The content between the opening and closing component tags
is received through children.
TypeScript can use readonly properties to
prevent reassignment through that typed reference.
interface UserProps {
readonly id: number;
name: string;
}
function User({
id,
name
}: UserProps) {
return (
<div>
<p>ID: {id}</p>
<p>Name: {name}</p>
</div>
);
}
A prop can accept more than one type using a union type.
interface MessageProps {
value: string | number;
}
function Message({
value
}: MessageProps) {
return <p>{value}</p>;
}
Literal types can restrict a prop to specific values.
interface ButtonProps {
type: "primary" | "secondary";
}
function Button({
type
}: ButtonProps) {
return (
<button className={type}>
Button
</button>
);
}
Event handler functions can be passed as typed props.
interface ButtonProps {
onClick: (
event: React.MouseEvent<HTMLButtonElement>
) => void;
}
function Button({
onClick
}: ButtonProps) {
return (
<button onClick={onClick}>
Click Me
</button>
);
}
interface CardProps {
title: string;
description: string;
}
function Card({
title,
description
}: CardProps) {
return (
<div>
<h2>{title}</h2>
<p>{description}</p>
</div>
);
}
<Card
title="TypeScript"
description="Learn TypeScript with React"
/>
React normally follows a one-way data flow where the parent passes data to the child through props.
function Parent() {
const name = "Rahul";
return (
<Child name={name} />
);
}
interface ChildProps {
name: string;
}
function Child({
name
}: ChildProps) {
return <h2>Hello {name}</h2>;
}
? for optional props.children.import { ReactNode } from "react";
interface Student {
id: number;
name: string;
course: string;
}
interface StudentCardProps {
student: Student;
onSelect: (id: number) => void;
children?: ReactNode;
}
function StudentCard({
student,
onSelect,
children
}: StudentCardProps) {
return (
<div>
<h2>
{student.name}
</h2>
<p>
ID: {student.id}
</p>
<p>
Course: {student.course}
</p>
{children}
<button
onClick={() =>
onSelect(student.id)
}
>
Select Student
</button>
</div>
);
}
function App() {
const student: Student = {
id: 101,
name: "Rahul",
course: "React Native"
};
const handleSelect = (id: number): void => {
console.log(
"Selected Student:",
id
);
};
return (
<StudentCard
student={student}
onSelect={handleSelect}
>
<p>
Student information
</p>
</StudentCard>
);
}
export default App;
This example combines object props, function props, optional children, interfaces, and event handling in one reusable React component.
? are required.? are optional.ReactNode can be used for children content.Question: Which TypeScript symbol is used to make a React prop optional?