We use cookies to enhance your experience on the site
CodeWorlds

Typing Functional Components

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.

React.FC vs Explicit Typing

There are two popular ways to type functional components in React:

Method 1: React.FC (Function Component)

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};

Method 2: Explicit Typing (Recommended)

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};

Why is Explicit Typing Recommended?

The React community is moving away from React.FC for several reasons:

  1. React.FC adds children by default - even when the component doesn't use them
  2. Explicit typing is more readable - you can see exactly what the component accepts
  3. Better compatibility - works identically with function and arrow function
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}

Component Return Type

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}
Go to CodeWorlds