How to fix Argument of type "(props: Props) => JSX.Element" is not assignable to type "React.ComponentType" in React
This TypeScript error occurs when passing a component to a prop or utility that expects React.ComponentType, but the function signature returns JSX.Element instead of the broader ReactNode type.
Quick fix
Fixes Argument of type "(props: Props) => JSX.Element" is not assignable to type "React.ComponentType"
// Before - too narrow
const MyComponent = (props: Props): JSX.Element => {
return <div>{props.children}</div>;
};
// After - compatible with ComponentType
const MyComponent = (props: Props): React.ReactNode => {
return <div>{props.children}</div>;
};- Change return type from JSX.Element to ReactNode
- Remove explicit return type annotation
- Use React.FC or React.FunctionComponent (TypeScript 5.1+)
- Fix array return values with Fragment
// Before - too narrowconst MyComponent = (props: Props): JSX.Element => {return <div>{props.children}</div>;};// After - compatible with ComponentTypeconst MyComponent = (props: Props): React.ReactNode => {return <div>{props.children}</div>;};Argument of type "(props: Props) => JSX.Element" is not assignable to type "React.ComponentType"
What this error means
This error appears when TypeScript detects a mismatch between what your component returns and what React.ComponentType expects. React.ComponentType is a union type that can represent both class and function components, and it expects function components to return ReactNode (which includes JSX.Element, strings, numbers, null, undefined, and more). When you explicitly type a function component as returning JSX.Element, TypeScript sees this as too narrow for React.ComponentType, which expects the more flexible ReactNode return type. This commonly happens when using higher-order components, render props, or passing components to libraries that expect React.ComponentType. The error indicates a type compatibility issue, not a runtime error - your component will work fine, but TypeScript's type system is preventing potentially unsafe type assignments.
Typical symptoms
- TypeScript compilation fails with "not assignable to type 'React.ComponentType'" error
- Error occurs when passing components to HOCs or component props
- Using function components with explicit JSX.Element return type
- Library prop types expect React.ComponentType but receive narrower types
- Error appears after upgrading TypeScript or @types/react versions
Common causes
- Function component explicitly typed to return JSX.Element instead of ReactNode
- Using React.FC or React.FunctionComponent with incompatible return types
- Passing components to props typed as React.ComponentType without matching signature
- Type definitions between your code and library expectations mismatch
- Using older TypeScript patterns that conflict with modern React type definitions
- Component returns JSX.Element[] (array) instead of single element or Fragment
How to fix "Argument of type "(props: Props) => JSX.Element" is not assignable to type "React.ComponentType""
The most straightforward fix is to update your component's return type to ReactNode, which is what React.ComponentType expects:
// Before - too narrow
const MyComponent = (props: Props): JSX.Element => {
return <div>{props.children}</div>;
};
// After - compatible with ComponentType
const MyComponent = (props: Props): React.ReactNode => {
return <div>{props.children}</div>;
};ReactNode is the appropriate return type for modern React components as it allows all valid return values (elements, strings, numbers, null, etc.).
Let TypeScript infer the return type automatically, which will typically infer the correct ReactNode type:
// Before - explicit but incompatible
const MyComponent = (props: Props): JSX.Element => {
return <div>{props.children}</div>;
};
// After - TypeScript infers the correct type
const MyComponent = (props: Props) => {
return <div>{props.children}</div>;
};TypeScript's inference is usually smart enough to determine the correct return type based on what you actually return.
If you're on TypeScript 5.1 or later with React 18+, React.FC is now a viable option:
// Modern React.FC usage
const MyComponent: React.FC<Props> = (props) => {
return <div>{props.children}</div>;
};
// Or with explicit children
type PropsWithChildren = Props & { children?: React.ReactNode };
const MyComponent: React.FC<PropsWithChildren> = (props) => {
return <div>{props.children}</div>;
};Note: React.FC was problematic in older versions, but TypeScript 5.1+ fixed the issues with implicit children and return types.
If your component returns an array of elements, wrap them in a Fragment:
// Before - returns JSX.Element[]
const MyComponent = (props: Props) => {
return [
<div key="1">First</div>,
<div key="2">Second</div>
];
};
// After - returns single ReactNode
const MyComponent = (props: Props) => {
return (
<>
<div>First</div>
<div>Second</div>
</>
);
};React.ComponentType expects a single ReactNode, not an array.
Ensure you're using compatible versions of TypeScript and @types/react:
# Check current versions
npm list typescript @types/react
# Update to latest versions
npm install --save-dev typescript@latest @types/react@latest @types/react-dom@latest
# Or with Yarn
yarn upgrade typescript @types/react @types/react-dom --latestMany type compatibility issues were resolved in TypeScript 5.1+ and React 18+ type definitions.
Advanced notes
Understanding React Type Hierarchy:
The React type system has several related but distinct types:
- JSX.Element: The most specific - represents the result of a JSX expression
- React.ReactElement: Functionally the same as JSX.Element
- React.ReactNode: The broadest - includes elements, strings, numbers, null, undefined, booleans, and arrays
- React.ComponentType<P>: Union of React.FC<P> | React.ComponentClass<P> - represents any valid component type
When to Use Which Type:
- For component return types: Use React.ReactNode or let TypeScript infer
- For props that accept renderable content: Use React.ReactNode
- For props that accept components: Use React.ComponentType<Props>
- For HOC return types: Use React.ComponentType<Props>
React.FC Evolution:
React.FC was controversial in the TypeScript community because:
- Pre-TypeScript 5.1: It implicitly added children to props (unwanted in many cases)
- It didn't allow returning strings or numbers directly
- It made generic components awkward to type
As of TypeScript 5.1 and React 18, these issues are resolved, making React.FC acceptable again. However, many teams prefer explicit prop typing without React.FC for clarity.
Generic Components:
If you're building generic components, avoid React.FC as it doesn't support generics well:
// Doesn't work well with React.FC
function GenericComponent<T>(props: { items: T[] }) {
return <div>{props.items.length}</div>;
}Library Integration:
Some popular libraries (React Router, React Redux, testing libraries) expect React.ComponentType for component props. Always ensure your component signatures match the expected type, typically by using ReactNode return types or letting TypeScript infer.
Frequently asked questions
- What does "Argument of type "(props: Props) => JSX.Element" is not assignable to" mean?
- ComponentType expects. Element, strings, numbers, null, undefined, and more). ComponentType, which expects the more flexible ReactNode return type.
- How do I fix "Argument of type "(props: Props) => JSX.Element" is not assignable to"?
- This TypeScript error occurs when passing a component to a prop or utility that expects React.ComponentType, but the function signature returns JSX.Element instead of the broader ReactNode type.
- What causes "Argument of type "(props: Props) => JSX.Element" is not assignable to"?
- Function component explicitly typed to return JSX.Element instead of ReactNode Using React.FC or React.FunctionComponent with incompatible return types Passing components to props typed as React.ComponentType without matching signature
- Is the "Argument of type "(props: Props) => JSX.Element" is not assignable to" error serious?
- It is a low-severity error โ more of a blocker than a risk. The steps above resolve it.