Repository navigation
[Strict TS API] NativeSyntheticEvent doesn't match BaseSyntheticEvent #57910
Copy link
Copy link
Open
Labels
Description
Description
My team uses unified codebase that share web and native code, so that is why a BaseSyntheticEvent event was used here.
import type {BaseSyntheticEvent} from 'react';
<TextInput onSubmitEditing={
(event: BaseSyntheticEvent) => {
event.bubbles; // boolean | undefined
// error: BaseSyntheticEvent require `boolean` only type
}}
/>this issue doesn't not exist in prev. RN versions
Steps to reproduce
see above
React Native Version
0.87.0
Affected Platforms
Runtime - Android, Runtime - iOS
Output of npx @react-native-community/cli info
System:
OS: macOS 26.5
CPU: (11) arm64 Apple M3 Pro
Memory: 1.27 GB / 36.00 GB
Shell:
version: 4.0.1
path: /opt/homebrew/bin/fish
Binaries:
Node:
version: 24.13.1
path: /usr/local/bin/node
Yarn:
version: 3.6.4
path: /opt/homebrew/bin/yarn
npm:
version: 11.8.0
path: /usr/local/bin/npm
Watchman:
version: 2025.09.01.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /Users/xdxd/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.2
- iOS 26.2
- macOS 26.2
- tvOS 26.2
- visionOS 26.2
- watchOS 26.2
Android SDK:
API Levels:
- "34"
- "35"
- "36"
Build Tools:
- 33.0.1
- 34.0.0
- 35.0.0
- 36.0.0
- 37.0.0
System Images:
- android-34 | Android TV ARM 64 v8a
- android-34 | Google TV ARM 64 v8a
- android-35 | Google APIs ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-36 | Android TV ARM 64 v8a
- android-36 | Google TV ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2026.1 AI-261.23567.138.2611.15646644
Xcode:
version: 26.2/17C52
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.13
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /Users/xdxd/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.2.0
wanted: 20.2.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.87.0
wanted: 0.87.0
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: false
Stacktrace or Logs
error TS2322: Type '(event: BaseSyntheticEvent) => void' is not assignable to type '(e: Readonly<{ bubbles: boolean | undefined; cancelable: boolean; currentTarget: number | ReactNativeElement; defaultPrevented: boolean; dispatchConfig: Readonly<{ registrationName: string; }>; ... 10 more ...; type: string; }>) => unknown'.
Types of parameters 'event' and 'e' are incompatible.
Type 'Readonly<{ bubbles: boolean | undefined; cancelable: boolean; currentTarget: number | ReactNativeElement; defaultPrevented: boolean; dispatchConfig: Readonly<{ registrationName: string; }>; ... 10 more ...; type: string; }>' is not assignable to type 'BaseSyntheticEvent<object, any, any>'.
Types of property 'bubbles' are incompatible.
Type 'boolean | undefined' is not assignable to type 'boolean'.
Type 'undefined' is not assignable to type 'boolean'.
27 <TextInput onSubmitEditing={(event: BaseSyntheticEvent) => {
MANDATORY Reproducer
Screenshots and Videos
...
Reactions are currently unavailable
Activity
retyui commentedon Aug 12, 2026
The next props need to be changed to make it compatible with React

aravi365 commentedon Aug 13, 2026
The reason this only shows up on 0.87 is that the two type surfaces disagree with each other.
The hand-written
Libraries/Types/CoreEventTypes.d.tshas:so on the legacy types these were assignable to
BaseSyntheticEvent. The Strict API types are generated from the Flow source instead, andCoreEventTypes.jsdeclaresbubbles: ?boolean,cancelable: ?boolean,eventPhase: ?number,isTrusted: ?booleanandtype: ?string.For what it's worth the Flow side looks like the accurate one. Those fields are copied straight off the native event payload. A
nullentry inSyntheticEvent.Interfacemeans "copy verbatim", and the constructor does:bubbles,cancelable,eventPhase,isTrustedandtypeare allnullentries in that Interface, so their runtime value is whatever the native payload carried, and native payloads generally don't include DOM event metadata. Soundefinedis a real case here, not a typing artifact.If that's right, then the
.d.tswas the inaccurate surface and tightening the generated types to matchBaseSyntheticEventwould paper over a genuine runtime value. Probably worth someone confirming which of the two is the intended contract before anything changes.retyui commentedon Sep 1, 2026
@aravi365 how a
typeprop can beundefined?aravi365 commentedon Sep 13, 2026
@retyui it's undefined whenever the native payload doesn't carry a
typekey.typeis one of thenullentries inSyntheticEvent.Interface, and for those the constructor copies the field straight off the native event (ReactFabric-dev.js, around line 810):The event name never ends up there. Fabric's
dispatchEvent(target, topLevelType, nativeEventParam)gets it as the separatetopLevelTypeargument and nothing writes it back ontonativeEvent.type. The only subclass,ResponderSyntheticEvent, just addstouchHistory.So unless a particular native event puts
typein its payload, you getundefined. Aconsole.log(event.type)in anonSubmitEditinghandler should show it. That's why Flow has it as?string.