You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
5.0: Narrowing from type-guards ignored when constructing JSX call (2604) #53178
We saw 8 errors in our codebase pop up. This might be a fairly common issue in React Native codebases or any codebase having types like React.ComponentType<any> | React.ReactElement.
import*asReactfrom'react'// `@types/react-native` FlatListProps['ListHeaderComponent']declareconstListHeaderComponent: React.ComponentType<any>|React.ReactElement// JSX element type 'ListHeaderComponent' does not have any construct or call signatures.(2604)constelementB=React.isValidElement(ListHeaderComponent) ? ListHeaderComponent : <ListHeaderComponent/>
-declare function isValidElement(maybeElement: unknown): maybeElement is React.ReactElement<unknown>+declare function isValidElement(maybeElement: unknown): maybeElement is React.ReactElement<any>
which requires a change in @types/react.
The change in @types/react-native makes more sense but means other type libraries need to update as well.
3rd option is making React.ReactElement default to React.ReactElement<unkown> instead of React.ReactElement<any> but that might be even more disruptive.
I'll fiddle with each alternative but I would appreciate if you could check if this new behavior in TypeScript is so valueable to warrant this breakage in the ecosystem.
🙁 Actual behavior
JSX element type 'ListHeaderComponent' does not have any construct or call signatures.(2604)
🙂 Expected behavior
No type error since isValidElement narrows to React.ReactElement i.e. the else branch should just be React.ComponentType<any>
I believe the root cause here - isValidElement and ReactElement having different default type arguments, thus resulting in subtyping assymmetry, is still the same. If you have a repro that doesn't depend on React we can bisect it and verify.
I'm not following the labelling here. It's considered a duplicate of an issue that was closed by the PR that caused it? Sounds more like you're saying this is intended behavior?
I'm also having a hard time trying to follow the thread here... I still have this issue on 5.0.3. Are we waiting on a change in @types/react then? Or is this supposed to be fixed already?
Reacted by Zach Hardesty, Sasha Chudesnov, Eduardo Portet and Noah Allen
This issue unfortunately isn't fixed! I'm still getting errors in Typescript 5.1.6. (I'm pretty sure this is the same issue.)
Here is a playground showing the error. The problem is that object is ReactElement<Props> does not work to narrow the types, but object is ReactElementdoes work.
Just a note: it works when u "forward" the PTS playground:
typeFoo={bar: string;}// Stub of ReactElement:interfaceReactElement<P=any>{props: P;}declarefunctionisValidElement<P>(object: {}|null|undefined): object is ReactElement<P>functiondoSomething<P>(input: Foo|ReactElement<P>){if(isValidElement(input)){returninput;}// Type should be narrowed, and it isreturninput.bar;}
Activity
RyanCavanaugh commentedon Mar 10, 2023
Duplicate #52232
eps1lon commentedon Mar 10, 2023
The linked issue repros in 4.9.4 while mine does not. Could you clarify why you think it is a duplicate?
RyanCavanaugh commentedon Mar 10, 2023
I believe the root cause here -
isValidElementandReactElementhaving different default type arguments, thus resulting in subtyping assymmetry, is still the same. If you have a repro that doesn't depend on React we can bisect it and verify.eps1lon commentedon Mar 11, 2023
So if it turns out to root cause is a dupe, you won't consider this a 5.0 regression even though it only started failing when going from 4.9 to 5.0?
eps1lon commentedon Mar 11, 2023
no React 4.9.5 no type errors
no react 5.0.0-rc type errors
Andarist commentedon Mar 19, 2023
Bisected to #52282
chore: revert TypeScript 5 because of JSX detection issues
RyanCavanaugh commentedon Mar 30, 2023
Right, this is basically the converse report of #50916
eps1lon commentedon Mar 30, 2023
I'm not following the labelling here. It's considered a duplicate of an issue that was closed by the PR that caused it? Sounds more like you're saying this is intended behavior?
typescript-bot commentedon Apr 2, 2023
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
greypants commentedon Apr 3, 2023
I'm also having a hard time trying to follow the thread here... I still have this issue on 5.0.3. Are we waiting on a change in @types/react then? Or is this supposed to be fixed already?
noahtallen commentedon Jul 31, 2023
This issue unfortunately isn't fixed! I'm still getting errors in Typescript 5.1.6. (I'm pretty sure this is the same issue.)
Here is a playground showing the error. The problem is that
object is ReactElement<Props>does not work to narrow the types, butobject is ReactElementdoes work.Andarist commentedon Aug 1, 2023
Just a note: it works when u "forward" the
PTS playground:rejetto commentedon Apr 20, 2025
an easy fix for the problem is to not use just ReactElement but
ReactElement<unknown>(if you don't know a more specific type)