TS2786: React TypeScript Component JSX Error
Problem Statement
When working with React and TypeScript, you might encounter the TS2786 error:
TS2786: 'ComponentName' cannot be used as a JSX component.
Its instance type 'ComponentName' is not a valid JSX element.
The types returned by 'render()' are incompatible with these types.
Type 'React.ReactNode' is not assignable to type 'import("/path/to/node_modules/@types/react/index").ReactNode'.
This error typically occurs when there are multiple, incompatible versions of React type definitions (@types/react
) in your project, causing TypeScript to become confused about which ReactNode
type definition to use.
Root Cause
The main cause of this error is version mismatch in React type definitions. Various packages in your dependency tree may require different versions of @types/react
, creating incompatible type definitions that conflict with each other.
Common scenarios include:
- Upgrading React (
@types/react
v18) while some dependencies still expect v17 - Multiple copies of
@types/react
in your node_modules - Third-party libraries with wildcard version requirements (
"@types/react": "*"
)
Solutions
1. Version Synchronization (Recommended)
Ensure all packages use compatible @types/react
versions:
Using Yarn:
{
"resolutions": {
"@types/react": "18.2.0",
"@types/react-dom": "18.2.0"
}
}
Using npm (v8+):
{
"overrides": {
"@types/react": "18.2.0",
"@types/react-dom": "18.2.0"
}
}
After adding these, delete node_modules
and your lock file (package-lock.json
or yarn.lock
), then reinstall dependencies.
2. TypeScript Configuration Fix
Add path aliasing to your tsconfig.json
:
{
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
}
}
}
3. Module Resolution Strategy
Configure TypeScript to use a compatible module resolution:
{
"compilerOptions": {
"moduleResolution": "bundler",
"skipLibCheck": true
}
}
4. Dependency Analysis
Identify which packages are causing version conflicts:
# Yarn
yarn why @types/react
# npm
npm explain @types/react
Common Scenarios and Fixes
Async Components
WARNING
Don't mark React components as async
directly. Async functions return Promises, which are not valid JSX elements.
Incorrect:
export async const Component = () => {
// Async operations
return <div>Content</div>;
}
Correct:
export const Component = () => {
const fetchData = async () => {
// Async operations
};
return <div>Content</div>;
}
Router Redirects
When using redirects in conditional rendering, ensure you return valid JSX:
Problematic:
if (!isLoggedIn) return router.push("/login");
Solution:
// Option 1: Return empty fragment
if (!isLoggedIn) {
router.push("/login");
return <></>;
}
// Option 2: Use framework-specific redirect component (Expo example)
import { Redirect } from "expo-router";
if (!isLoggedIn) return <Redirect href="/login" />;
Children Rendering
When returning children
directly, wrap them in a fragment:
// Problematic
return children;
// Fixed
return <>{children}</>;
Framework-Specific Solutions
React Native
Ensure your tsconfig.json
includes proper type definitions:
{
"compilerOptions": {
"types": ["react-native", "jest"]
}
}
Styled Components v6+
If using styled-components v6+, uninstall @types/styled-components
as the types are now bundled:
npm uninstall @types/styled-components
# or
yarn remove @types/styled-components
Verification and Cleanup
After applying fixes:
- Delete
node_modules
and lock files - Clear package manager cache (
npm cache clean --force
oryarn cache clean
) - Reinstall dependencies
- Verify only one version of
@types/react
is installed:
npm list @types/react
# or
yarn list --pattern "@types/react"
Prevention
To avoid this issue in the future:
- Pin specific versions for critical type packages
- Regularly audit dependencies with
npm audit
oryarn audit
- Use consistent React versions across all dependencies
- Consider using
npm dedupe
oryarn dedupe
to eliminate duplicate packages
By understanding the root cause and applying the appropriate solution for your specific setup, you can resolve the TS2786 error and maintain a stable React TypeScript development environment.