I first started using TypeScript with React, and I quickly realized how much cleaner and safer my code became. Gone were the days of guessing prop types or dealing with runtime errors that could’ve been caught earlier.
Over the years, I’ve built dozens of production-grade React apps, from dashboards to e-commerce platforms, and TypeScript has become one of my must-have tools. In this post, I’ll walk you through how I create React function components with TypeScript, using real-world examples that make sense for developers in the U.S. market.
What Are React Function Components?
React function components are simply JavaScript or TypeScript functions that return JSX. In modern React (since version 16.8), function components are the standard way to build UI because they’re lightweight and work seamlessly with Hooks.
When we combine them with TypeScript, we achieve type safety, auto-completion, and improved maintainability, all of which are essential for scalable applications.
Set Up a React + TypeScript Project
Before we begin coding, let’s ensure you have the correct setup. The easiest way to create a new React project with TypeScript is by using Vite or Create React App.
Method 1: Use Vite (Recommended for Speed)
Here’s how I usually set up a TypeScript React project using Vite.
npm create vite@latest my-react-ts-app -- --template react-ts
cd my-react-ts-app
npm install
npm run devI executed the above example code and added the screenshot below.

This creates a React + TypeScript project with a blazing-fast development environment.
Once it’s running, open the project in VS Code and you’re ready to start building.
Method 2: Use Create React App
If you prefer the traditional way, you can still use Create React App.
npx create-react-app my-react-ts-app --template typescript
cd my-react-ts-app
npm startBoth methods achieve the same result: a ready-to-use React + TypeScript setup. Now that we have our environment ready, let’s dive into building components.
Create a Simple Function Component in TypeScript
Let’s start with the basics, a simple greeting component that displays a user’s name.
Above the code, I define a TypeScript type for the props. This ensures that when I use the component, I’ll get instant feedback if I pass incorrect data types.
import React from "react";
type GreetingProps = {
name: string;
age?: number; // Optional prop
};
const Greeting: React.FC<GreetingProps> = ({ name, age }) => {
return (
<div>
<h2>Hello, {name}!</h2>
{age && <p>You are {age} years old.</p>}
</div>
);
};
export default Greeting;I executed the above example code and added the screenshot below.

In this code, I used the React.FC type (short for Function Component). It automatically includes the children prop and ensures the return type is valid JSX.
You can now use it like this:
<Greeting name="John" age={30} />This simple structure forms the foundation for all React components you’ll build with TypeScript.
Type Props Without React.FC
Some developers prefer not to use React.FC. I personally use both, depending on the situation.
Here’s the same example without using React.FC.
type GreetingProps = {
name: string;
city: string;
};
function Greeting({ name, city }: GreetingProps) {
return (
<div>
<h2>Hi, {name} from {city}!</h2>
</div>
);
}
export default Greeting;This approach gives you more control over the component’s return type and avoids automatically including children when you don’t need them. I often use this style for smaller, stateless components.
Use Children in TypeScript Components
Sometimes, you’ll want to pass JSX as children. Here’s how I handle that in a strongly typed way.
type CardProps = {
title: string;
children: React.ReactNode;
};
const Card = ({ title, children }: CardProps) => {
return (
<div style={{ border: "1px solid #ccc", padding: "10px", borderRadius: "6px" }}>
<h3>{title}</h3>
<div>{children}</div>
</div>
);
};
export default Card;Now you can wrap any content inside the Card component:
<Card title="User Info">
<p>Location: New York, USA</p>
<p>Status: Active</p>
</Card>Using React.ReactNode for children ensures flexibility; you can pass text, elements, or even other components safely.
Typing Event Handlers in TypeScript
One of the most common challenges I faced early on was typing event handlers correctly.
Let’s look at a clean example that handles a text input.
import React, { useState } from "react";
const SearchBar: React.FC = () => {
const [query, setQuery] = useState("");
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
};
return (
<div>
<input
type="text"
placeholder="Search products..."
value={query}
onChange={handleChange}
/>
<p>Searching for: {query}</p>
</div>
);
};
export default SearchBar;Here, the event type is React.ChangeEvent<HTMLInputElement> ensures that e.target.value is recognized as a string. This prevents common bugs, especially when dealing with form inputs or custom components.
Typing Component State and Hook
TypeScript automatically infers types from the initial state, but you can explicitly define them when needed.
import React, { useState } from "react";
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
return (
<div>
<h2>Counter: {count}</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;By explicitly typing the state as a number, you ensure that setCount will only accept numeric values. This is especially useful when dealing with complex state objects or arrays.
Typing Components with Default Props
Sometimes, you’ll want to provide default values for props. Here’s how I do it in TypeScript.
type ButtonProps = {
label: string;
color?: string;
};
const Button = ({ label, color = "blue" }: ButtonProps) => {
return (
<button style={{ backgroundColor: color, color: "white", padding: "8px 12px" }}>
{label}
</button>
);
};
export default Button;The default value for color ensures that even if no color is passed, the button still renders properly. This small detail improves usability and prevents undefined behavior.
Typing Components with Generics
Generics are powerful when creating reusable components that can handle multiple data types.
type ListProps<T> = {
items: T[];
renderItem: (item: T) => React.ReactNode;
};
function List<T>({ items, renderItem }: ListProps<T>) {
return <ul>{items.map((item, index) => <li key={index}>{renderItem(item)}</li>)}</ul>;
}
export default List;You can now use it with different data types:
<List
items={["Apples", "Bananas", "Cherries"]}
renderItem={(item) => <strong>{item}</strong>}
/>
<List
items={[{ id: 1, name: "John" }, { id: 2, name: "Alice" }]}
renderItem={(user) => <p>{user.name}</p>}
/>This pattern makes components highly flexible and strongly typed, which is great for building reusable UI libraries.
Typing React Hooks (Custom Hooks Example)
Let’s take it a step further and create a custom hook with TypeScript.
import { useState } from "react";
function useToggle(initialValue: boolean = false): [boolean, () => void] {
const [value, setValue] = useState<boolean>(initialValue);
const toggle = () => setValue((prev) => !prev);
return [value, toggle];
}
export default useToggle;This hook returns a tuple containing the current state and a toggle function. TypeScript ensures that both values are always correctly typed.
Usage example:
const [isOpen, toggleOpen] = useToggle();Working with React Function Components in TypeScript has completely changed how I approach frontend development.
It’s not just about catching errors early; it’s about writing code that’s predictable, maintainable, and easier for teams to scale.
If you’re building modern React apps, whether it’s a U.S.-based e-commerce platform or a SaaS dashboard, TypeScript will help you write cleaner and more reliable components.
Over time, you’ll notice how your codebase becomes more self-documenting, and your development speed actually increases once you get used to the typings.
I hope this guide helps you confidently start building your next TypeScript-powered React project.
You may also read:
- Pass Props to a Component in React
- Explain Tabs Component in React
- React Component Testing Best Practices
- Convert SVG to React Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.