在@types/react "^18.0.17"版本中如何为React函数组件添加类型定义?React.FC类型不再包含children属性时应如何类型化组件?
@types/react@18.0.17 Hey there! Let's break down these two common React TypeScript questions you're facing, since you're working with @types/react@18.0.17:
1. Correctly Typing React Function Components in @types/react@18.0.17
In React 18's type definitions, the most clear and flexible approach is to explicitly define your component's Props type rather than relying on implicit behavior. Here's how to do it properly:
Option 1: Explicit Props Type (Recommended)
Define a custom type for your component's props, then pass it as the type for your function's parameters. This makes exactly what your component accepts crystal clear:
import React from 'react'; // Define all props your component needs type GreetingProps = { name: string; // Add children explicitly if your component uses them children?: React.ReactNode; }; // Use the props type directly in your function component const Greeting = ({ name, children }: GreetingProps) => { return ( <div> Hello, {name}! {children} </div> ); };
Option 2: Using React.FC (Still Valid)
If you prefer using React.FC, you can still do so—but note that React 18 removed the default children property from React.FC. You'll need to add it to your props type explicitly:
import React from 'react'; type ButtonProps = { label: string; children?: React.ReactNode; // Explicitly include children }; const Button: React.FC<ButtonProps> = ({ label, children }) => { return <button>{label}{children}</button>; };
2. Typing Components When React.FC Doesn't Include children Anymore
The removal of default children from React.FC was intentional—it encourages explicit prop definitions, preventing accidental reliance on children that your component might not actually support. Here are the best ways to handle this:
1. Explicitly Declare children in Your Props Type
This is the most straightforward approach. Just add children?: React.ReactNode (or children: React.ReactNode if it's required) to your custom props type:
import React from 'react'; type CardProps = { title: string; children: React.ReactNode; // Required children (no optional `?`) }; const Card = ({ title, children }: CardProps) => { return ( <div className="card"> <h2>{title}</h2> <div className="card-content">{children}</div> </div> ); };
2. Use React.PropsWithChildren Helper Type
If you want to avoid manually writing children every time, use the built-in PropsWithChildren type to wrap your component's core props. It automatically adds an optional children property:
import React from 'react'; // Define only your component's unique props type AlertProps = { type: 'success' | 'error'; message: string; }; // Wrap with PropsWithChildren to include children const Alert = ({ type, message, children }: React.PropsWithChildren<AlertProps>) => { return ( <div className={`alert alert-${type}`}> {message} {children} </div> ); };
3. Ditch React.FC Altogether (Community Favorite)
Many TypeScript developers now prefer skipping React.FC entirely, as it removes any implicit behavior and keeps your component definitions concise. This works exactly like the explicit props type approach:
import React from 'react'; type TodoItemProps = { task: string; isCompleted: boolean; }; // No React.FC needed—just a regular function with typed props const TodoItem = ({ task, isCompleted }: TodoItemProps) => { return ( <li style={{ textDecoration: isCompleted ? 'line-through' : 'none' }}> {task} </li> ); };
The key takeaway here is to make your component's dependencies explicit. This makes your code easier to read, maintain, and debug!
内容的提问来源于stack exchange,提问作者jsnoob123

