How to fix Props interface must extend React.PropsWithChildren for correct typing in React

ReactBEGINNERLOWUpdated Dec 10, 2025ยท 87 views

TypeScript requires explicit typing for the children prop in React components. Using React.PropsWithChildren ensures the children prop is correctly typed as ReactNode and helps prevent type errors when rendering components with child elements.

Quick fix

Fixes Props interface must extend React.PropsWithChildren for correct typing

import React from 'react';

interface ButtonProps {
  backgroundColor: string;
  onClick: () => void;
}

// Wrap your props with PropsWithChildren
const Button = ({ backgroundColor, onClick, children }: React.PropsWithChildren<ButtonProps>) => {
  return (
    <button style={{ backgroundColor }} onClick={onClick}>
      {children}
    </button>
  );
};
  1. Use PropsWithChildren as a generic wrapper
  2. Extend PropsWithChildren in your interface
  3. Manually type children with ReactNode (alternative)
  4. Update React.FC usage for React 18+
react โ€” error
import React from 'react';
interface ButtonProps {
backgroundColor: string;
onClick: () => void;
}
// Wrap your props with PropsWithChildren
const Button = ({ backgroundColor, onClick, children }: React.PropsWithChildren<ButtonProps>) => {
return (
<button style={{ backgroundColor }} onClick={onClick}>
{children}
</button>
);
};
Props interface must extend React.PropsWithChildren for correct typing

What this error means

This TypeScript error occurs when you try to use the `children` prop in a React component without properly typing it in your props interface. Since React 18, the `children` prop is no longer implicitly included in React.FC, requiring developers to explicitly type it. The `React.PropsWithChildren` utility type is React's built-in solution for adding the children prop to your component's props. It's defined as `type PropsWithChildren<P> = P & { children?: ReactNode }`, which merges your custom props with an optional children property typed as ReactNode. Without proper typing, TypeScript cannot verify that your component is being used correctly, leading to potential runtime errors when components expect children but receive none, or when the wrong type of children is passed.

Typical symptoms

  • TypeScript error: Property "children" does not exist on type Props
  • Component accepts children at runtime but TypeScript shows type error
  • IDE shows red squiggly lines when trying to access props.children
  • Build fails with TS2339: Property "children" does not exist
  • React.FC components fail to compile after upgrading to React 18

Common causes

  1. Props interface does not include children property or extend PropsWithChildren
  2. React 18 removed implicit children prop from React.FC type definition
  3. Manually typed children property with incorrect type (not ReactNode)
  4. Using React.FC without explicitly adding children to custom props interface
  5. Migrating from older React versions without updating type definitions

How to fix "Props interface must extend React.PropsWithChildren for correct typing"

1Use PropsWithChildren as a generic wrapper

The most straightforward approach is to wrap your props interface with React.PropsWithChildren:

typescript
import React from 'react';

interface ButtonProps {
  backgroundColor: string;
  onClick: () => void;
}

// Wrap your props with PropsWithChildren
const Button = ({ backgroundColor, onClick, children }: React.PropsWithChildren<ButtonProps>) => {
  return (
    <button style={{ backgroundColor }} onClick={onClick}>
      {children}
    </button>
  );
};

This automatically adds children?: ReactNode to your props type.

2Extend PropsWithChildren in your interface

For better reusability, have your interface extend React.PropsWithChildren:

typescript
import React from 'react';

interface CardProps extends React.PropsWithChildren {
  title: string;
  variant?: 'primary' | 'secondary';
}

const Card = ({ title, variant = 'primary', children }: CardProps) => {
  return (
    <div className={`card card-${variant}`}>
      <h2>{title}</h2>
      <div className="card-content">{children}</div>
    </div>
  );
};

This approach is cleaner when you have multiple props and allows extending multiple interfaces.

3Manually type children with ReactNode (alternative)

If you need more control over whether children is required or optional, manually add it to your props:

typescript
import React, { ReactNode } from 'react';

// Optional children
interface ContainerProps {
  className?: string;
  children?: ReactNode;
}

// Required children
interface WrapperProps {
  id: string;
  children: ReactNode; // No question mark makes it required
}

const Container = ({ className, children }: ContainerProps) => {
  return <div className={className}>{children}</div>;
};

const Wrapper = ({ id, children }: WrapperProps) => {
  return <section id={id}>{children}</section>;
};

Note that PropsWithChildren makes children optional by default. Use explicit typing if children should be required.

4Update React.FC usage for React 18+

If you're using React.FC, you must now explicitly include children:

typescript
import React from 'react';

// Before React 18 (children was implicit)
// const Layout: React.FC<{ title: string }> = ({ title, children }) => { ... }

// After React 18 (children must be explicit)
interface LayoutProps {
  title: string;
  children?: React.ReactNode;
}

const Layout: React.FC<LayoutProps> = ({ title, children }) => {
  return (
    <div>
      <h1>{title}</h1>
      <main>{children}</main>
    </div>
  );
};

// Or use PropsWithChildren
const Layout: React.FC<React.PropsWithChildren<{ title: string }>> = ({ title, children }) => {
  return (
    <div>
      <h1>{title}</h1>
      <main>{children}</main>
    </div>
  );
};

Many developers now prefer to avoid React.FC altogether and use regular function declarations.

Advanced notes

PropsWithChildren vs Manual ReactNode

The PropsWithChildren utility type always makes children optional (children?: ReactNode). If your component requires children, you should manually type it as children: ReactNode (without the question mark).

Why React 18 Changed This

Prior to React 18, React.FC implicitly included children, which caused issues:
- Components that shouldn't accept children were typed as accepting them
- It violated the principle of explicit is better than implicit
- It made TypeScript types less accurate

Custom PropsWithChildren Variants

You can create your own utility types for more control:

typescript
// Required children
type PropsWithRequiredChildren<P = unknown> = P & { children: ReactNode };

// Specific children type
type PropsWithStringChildren<P = unknown> = P & { children: string };

Type Safety Limitations

While TypeScript can enforce that children exists, it cannot deeply validate the structure of JSX children at compile time. You cannot make children "type safe" in the sense of enforcing specific component types or structures through TypeScript alone.

Frequently asked questions

What does "Props interface must extend React.PropsWithChildren for correct typing" mean?
This TypeScript error occurs when you try to use the children prop in a React component without properly typing it in your props interface. FC, requiring developers to explicitly type it. PropsWithChildren utility type is React's built-in solution for adding the children prop to your component's props.
How do I fix "Props interface must extend React.PropsWithChildren for correct typing"?
TypeScript requires explicit typing for the children prop in React components. Using React.PropsWithChildren ensures the children prop is correctly typed as ReactNode and helps prevent type errors when rendering components with child elements.
What causes "Props interface must extend React.PropsWithChildren for correct typing"?
Props interface does not include children property or extend PropsWithChildren React 18 removed implicit children prop from React.FC type definition Manually typed children property with incorrect type (not ReactNode)
Is the "Props interface must extend React.PropsWithChildren for correct typing" error serious?
It is a low-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading