Props are the cosmic communication between components. TypeScript lets you precisely define what data can be transmitted - it's like a communication protocol on the spaceship.
Interfaces are the most common way to define prop types in React:
1// An interface defines the "shape" of data
2interface CrewMemberProps {
3 name: string;
4 rank: string;
5 experience: number;
6 specialization: string;
7}
8
9function CrewMember({ name, rank, experience, specialization }: CrewMemberProps) {
10 return (
11 <div>
12 <h3>{name}</h3>
13 <p>Rank: {rank}</p>
14 <p>Years of experience: {experience}</p>
15 <p>Specialization: {specialization}</p>
16 </div>
17 );
18}
19
20// Usage - TypeScript checks all props
21<CrewMember
22 name="Nova"
23 rank="Captain"
24 experience={15}
25 specialization="Navigation"
26/>Not all props are required. Use the
? sign to mark a prop as optional:1interface MissionProps {
2 title: string; // required
3 description: string; // required
4 priority?: "low" | "medium" | "high"; // optional
5 deadline?: Date; // optional
6 assignedCrew?: string[]; // optional
7}
8
9function MissionCard({ title, description, priority = "medium", deadline, assignedCrew }: MissionProps) {
10 return (
11 <div>
12 <h3>{title}</h3>
13 <p>{description}</p>
14 <span>Priority: {priority}</span>
15 {deadline && <p>Deadline: {deadline.toLocaleDateString()}</p>}
16 {assignedCrew && (
17 <ul>
18 {assignedCrew.map(member => <li key={member}>{member}</li>)}
19 </ul>
20 )}
21 </div>
22 );
23}
24
25// Can be used without optional props
26<MissionCard title="Recon" description="Sector 7 reconnaissance" />
27
28// Or with all of them
29<MissionCard
30 title="Recon"
31 description="Sector 7 reconnaissance"
32 priority="high"
33 assignedCrew={["Nova", "Ra"]}
34/>The
children prop is a special prop in React. Here's how to type it correctly:1// React.ReactNode - accepts anything React can render
2interface PanelProps {
3 title: string;
4 children: React.ReactNode;
5}
6
7function Panel({ title, children }: PanelProps) {
8 return (
9 <div className="panel">
10 <h2>{title}</h2>
11 <div className="content">{children}</div>
12 </div>
13 );
14}
15
16// Usage
17<Panel title="Mission Data">
18 <p>Status: active</p>
19 <MissionCard title="Recon" description="..." />
20</Panel>You can also use
type instead of interface:1// Type alias - alternative to interface
2type ButtonVariant = "primary" | "secondary" | "danger";
3
4type ButtonProps = {
5 label: string;
6 variant: ButtonVariant;
7 disabled?: boolean;
8 onClick: () => void;
9};
10
11// Interface - can be extended
12interface BaseProps {
13 id: string;
14 className?: string;
15}
16
17interface ShipProps extends BaseProps {
18 name: string;
19 speed: number;
20}
21
22// ShipProps has: id, className, name, speedInterfaces can be combined and extended, creating more complex structures:
1interface Coordinates {
2 x: number;
3 y: number;
4 z: number;
5}
6
7interface SpaceObject {
8 name: string;
9 coordinates: Coordinates;
10}
11
12interface Planet extends SpaceObject {
13 radius: number;
14 habitable: boolean;
15 atmosphere: string[];
16}
17
18interface Star extends SpaceObject {
19 temperature: number;
20 luminosity: number;
21 spectralClass: string;
22}