In React, every component is a function. TypeScript lets us precisely define what that function accepts (props) and what it returns (JSX). It's like an operating manual for each module on the spaceship.
There are two popular ways to type functional components in React:
1import React from 'react';
2
3// React.FC automatically adds the children type and return type
4const StarInfo: React.FC = () => {
5 return <p>Star information</p>;
6};
7
8// React.FC with props
9interface StarProps {
10 name: string;
11 brightness: number;
12}
13
14const StarCard: React.FC<StarProps> = ({ name, brightness }) => {
15 return (
16 <div>
17 <h3>{name}</h3>
18 <p>Brightness: {brightness}</p>
19 </div>
20 );
21};1// Explicit typing - more transparent and flexible
2interface StarProps {
3 name: string;
4 brightness: number;
5}
6
7function StarCard({ name, brightness }: StarProps): JSX.Element {
8 return (
9 <div>
10 <h3>{name}</h3>
11 <p>Brightness: {brightness}</p>
12 </div>
13 );
14}
15
16// Or as an arrow function
17const StarCardArrow = ({ name, brightness }: StarProps): JSX.Element => {
18 return (
19 <div>
20 <h3>{name}</h3>
21 <p>Brightness: {brightness}</p>
22 </div>
23 );
24};The React community is moving away from React.FC for several reasons:
1// React.FC - children is always available (even if unnecessary)
2const Badge: React.FC<{ label: string }> = ({ label, children }) => {
3 return <span>{label}{children}</span>; // children may be undefined
4};
5
6// Explicit typing - children must be explicitly added
7interface BadgeProps {
8 label: string;
9}
10
11function Badge({ label }: BadgeProps): JSX.Element {
12 return <span>{label}</span>; // no children, because it's not in props
13}A React component can return different types:
1// JSX.Element - most commonly used
2function Planet(): JSX.Element {
3 return <div>Mars</div>;
4}
5
6// React.ReactElement - more precise
7function Planet(): React.ReactElement {
8 return <div>Mars</div>;
9}
10
11// React.ReactNode - most flexible (JSX, string, number, null)
12function MaybeContent(): React.ReactNode {
13 return null; // can return null
14}
15
16// In practice, we most often omit the return type
17// TypeScript infers it automatically
18function Planet() {
19 return <div>Mars</div>; // TypeScript knows this is JSX.Element
20}