-
-
Notifications
You must be signed in to change notification settings - Fork 151
Description
Inspired by the great findings Codex had in #844, I asked it to review the complete rescript-react-native codebase against docs and TypeScript typedefs.
Below are the unedited findings. Not all will be valid/actionable, as oftentimes the bindings choose stricter typings intentionally for good reason.
Review Findings
Reviewed against React Native 0.81.0 TypeScript definitions, which matches this package's declared peer dependency. This document expands the initial spot review into a broader public-surface audit of the bindings under src/apis, src/components, and src/elements.
Findings
-
[P1]Bindings still target root exports that React Native 0.81 does not publicly export anymore: YellowBox.res, SoundManager.res, and ViewPagerAndroidMethods.res. Inreact-native@0.81.0,types/index.d.tsandindex.jsexpose none ofYellowBox,SoundManager, orViewPagerAndroid, so these bindings can resolve missing properties at runtime. -
[P1]The package is missing a substantial set of public React Native 0.81 exports entirely. The RN export list includes modules such asI18nManager,RCTDeviceEventEmitter,RCTNativeAppEventEmitter,registerCallableModule,requireNativeComponent,Systrace,PushNotificationIOS,TurboModuleRegistry,codegenNativeCommands,codegenNativeComponent,ErrorUtils,RootTag,LayoutConformance, andDevMenu, but there are no corresponding bindings under src/apis or src/components. This is a package-level completeness gap against RN 0.81’s public surface. -
[P1]Linkingmodels async APIs as sync or opaque values in Linking.res.openSettingsispromise<'a>instead ofPromise<void>, and bothsendIntentoverloads returnunit, while React Native 0.81 types them asPromise<void>. That prevents correct awaiting and error handling for a public API. -
[P1]Imagehas multiple static API mismatches in Image.res.resizeMethodis missing'none';loadingIndicatorSourceis typed asarray<Source.t>instead of a single source;prefetchreturns a request id instead ofPromise<bool>;queryCachereturnsunitinstead of a promise of cache-state map; and the promise overloads forgetSize, plusgetSizeWithHeadersandprefetchWithMetadata, are missing entirely. -
[P1]SectionList’s section shape is not compatible with React Native’s public typing in VirtualizedSectionList.res. React Native defines each section asSectionBase & SectionT, so custom fields live directly onsection; this binding forces them undersectionData?. Standard RN usage likesection.titlein headers will not type-check naturally here. -
[P1]The exported top-levelAnimated.timing,Animated.spring, andAnimated.decayare aliased fromValue.*at Animated.res, so they only acceptAnimated.Value. React Native 0.81 types them forAnimated.Value | Animated.ValueXY, andspringalso supports richertoValueshapes including colors and animated values. Valid RN animation calls are rejected by this binding surface. -
[P1]VirtualizedListmis-types theonStartReachedcallback payload in VirtualizedList.res. The binding uses{distanceFromEnd: float}for both start and end callbacks, while RN 0.81 uses{distanceFromStart: number}foronStartReached. Consumers matching on the field name cannot write the documented RN callback shape. -
[P2]AppRegistryhas several wrong signatures in AppRegistry.res.registerComponentreturnsunitinstead ofstring,unmountApplicationComponentAtRootTagtakesstringinstead ofnumber, and public 0.81 APIs such assetRootViewStyleProvider,setSurfaceProps, andsetComponentProviderInstrumentationHookare missing. -
[P2]Pressableis materially narrower than RN in Pressable.res.childrenonly accepts the render-prop form,styleonly accepts the callback form,hitSlopandpressRetentionOffsetcannot be numbers, and props likecancelable,delayHoverIn, anddelayHoverOutare absent. -
[P2]StatusBaris incomplete and over-strict in StatusBar.res.setHidden,setBarStyle, andsetBackgroundColorrequire their second parameter even though RN marks it optional, and the stack-entry APIspushStackEntry,popStackEntry, andreplaceStackEntryare missing. -
[P2]NativeEventEmitterloses part of the actual API shape in NativeEventEmitter.res. The constructor is required here but optional in RN types,listenerCountis typed as returningunitinstead ofnumber, andaddListeneromits the optionalcontextparameter. -
[P2]AccessibilityInfois behind the current RN surface in AccessibilityInfo.res. The binding missesisHighTextContrastEnabled,isDarkerSystemColorsEnabled,announceForAccessibilityWithOptions, andsendAccessibilityEvent, and its event union omits change events such aschange,highTextContrastChanged, anddarkerSystemColorsChanged. -
[P2]AppStateunder-models the current API in AppState.res. RN 0.81 exposesisAvailable, but the binding does not. TheaddEventListenerbinding also treats all event kinds as if they share one callback shape, while the TS surface models the API aroundAppStateEventandNativeEventSubscription. -
[P2]Appearancehas both type and event-shape drift in Appearance.res.setColorSchemeis narrower than RN because it does not allownull/undefined, andaddChangeListenerincorrectly takesunit => unitinstead of a callback receiving{colorScheme}preferences. -
[P2]BackHandlerstill exposes an obsolete API surface in BackHandler.res. RN 0.81 types only the'hardwareBackPress'event and no longer includesremoveEventListener, but this binding still exports both an extra#backPressevent case andremoveEventListener. -
[P2]Dimensionsis missing the publicsetAPI in Dimensions.res. RN 0.81 exposesDimensions.set(dims)for native-driven updates, but the binding omits it entirely. -
[P2]Keyboardis missing public methods from RN 0.81 in Keyboard.res.scheduleLayoutAnimationandmetrics()are absent. That leaves part of the documented keyboard coordination API unavailable. -
[P2]LayoutAnimationis incomplete in LayoutAnimation.res.configureNextlacks the optional failure callback, and RN’s exportedTypes,Properties, andconfigCheckermembers are missing. The convenience methodseaseInEaseOut,linear, andspringalso omit their optional completion callback. -
[P2]Sharehas an incorrect overload in Share.res. RN 0.81 exposes a singleshare(content, options?) => Promise<ShareAction>, while this binding splits outshareWithOptionsreturningpromise<bool>, which does not match the public contract. -
[P2]Platformis dramatically incomplete in Platform.res. The binding exposes onlyPlatform.OS, but RN 0.81 also exposesVersion,constants,isTV,isTesting, andselect. It also omits the'native'discriminant present inPlatformOSType. -
[P2]PermissionsAndroidis stale in PermissionsAndroid.res. The permission constants are missingREAD_MEDIA_VISUAL_USER_SELECTED, and the deprecated-but-still-typedcheckPermissionandrequestPermissionAPIs are absent from the public binding surface. -
[P2]UIManageronly exposes a small subset of RN’s public API in UIManager.res. Public methods such asmeasure,measureInWindow,measureLayout,getViewManagerConfig,hasViewManagerConfig, anddispatchViewManagerCommandare missing. -
[P2]ActionSheetIOSis narrower than RN in ActionSheetIOS.res.destructiveButtonIndexshould accept bothnumberandnumber[];disabledButtonIndicesshould be an array; and public options such asanchor,userInterfaceStyle, anddisabledButtonTintColorare missing. -
[P2]Alertis missing theuserInterfaceStyleoption in Alert.res. RN 0.81 exposes it onAlertOptions, but this binding does not. -
[P2]LogBoxis too narrow in LogBox.res.ignoreLogsonly acceptsarray<string>but RN accepts(string | RegExp)[];ignoreAllLogsomits its optional boolean parameter; and the publicinstallanduninstallmethods are missing. -
[P2]DevSettingsshould expose a single optional-argumentreload(reason?)API, not two separate bindings in DevSettings.res. RN 0.81 also modelsDevSettingsas extendingNativeEventEmitter, which this binding does not surface. -
[P2]Settingsis narrower than RN in Settings.res.getis typed as returningstringinstead ofany,watchKeysdoes not support the single-string overload, andwatchTokenis opaque instead of the numeric watch id RN returns. -
[P2]Buttondoes not match RN’s required prop shape in Button.res.titleis optional locally but required in RN 0.81. That weakens a key required prop from the public API. -
[P2]Switchis missing public props in Switch.res. RN 0.81 includesonChangeplus deprecated compatibility propsonTintColor,thumbTintColor, andtintColor, but the binding does not. -
[P2]TouchableWithoutFeedbackis narrower than RN in TouchableWithoutFeedback.res.childrenis limited toReact.elementinstead ofReactNode;hitSlopandpressRetentionOffsetcannot be numbers; and props such asrejectResponderTermination,focusable,id, andstyleare missing. -
[P2]TouchableOpacitydiverges from RN in TouchableOpacity.res. It is missing the TV/Android navigation propsnextFocusDown,nextFocusForward,nextFocusLeft,nextFocusRight, andnextFocusUp, and it exposesfocusedOpacity, which is not part of the RN 0.81 TypeScript surface. -
[P2]TouchableNativeFeedbackunder-models its background API in TouchableNativeFeedback.res.Rippleis missing the optionalrippleRadiusparameter, the selectable background helpers are missing their optional radius parameter, and the background shape is opaque instead of reflecting the discriminated objects RN exposes. -
[P2]InputAccessoryViewis narrower than RN in InputAccessoryView.res.childrenis typed asReact.elementinstead ofReactNode. -
[P2]Modalis incomplete in Modal.res. RN 0.81’sModalPropsincludeViewProps, but this binding does not spread them at all. It also missesallowSwipeDismissal, narrowschildrentoReact.element, and uses narrower event callback signatures foronShowandonRequestClose. -
[P2]RefreshControlhas a shape mismatch in RefreshControl.res. RN 0.81 typessizeas a numeric constant-backed value and exposes staticRefreshControl.SIZE, but the binding replaces that with a closed polymorphic variant and omits the static. -
[P2]DrawerLayoutAndroidhas a couple of public-contract mismatches in DrawerLayoutAndroid.res.renderNavigationViewis required in RN but optional here, andonDrawerStateChangedis typed with lowercase states even though the RN typings use'Idle' | 'Dragging' | 'Settling'. -
[P2]Textis materially incomplete in Text.res. RN 0.81 includes props such asdynamicTypeRamp,lineBreakMode,id, andpointerEvents, but the binding omits them. It also models Android data detection asdataDetectorTypes?: array<dataDetectorType>instead of RN’s singulardataDetectorTypeprop and current value set. -
[P2]Viewis missing several current public props in View.res. RN 0.81 includesid,focusable,tabIndex, AndroidonBlur/onFocus, TV parallax props, andcollapsableChildren, but the binding omits them.childrenis also narrowed toReact.elementinstead ofReactNode, andhitSlopcannot be a number. -
[P2]TextInputis behind RN 0.81 in TextInput.res. Public props such asdisableKeyboardShortcuts,passwordRules,selectionState,cursorColor,selectionHandleColor,lineBreakModeIOS, andsmartInsertDeleteare missing. ThetextContentTypeunion is stale and omits newer iOS values likecreditCardExpiration,birthdate, andcellularIMEI, anddataDetectorTypesis modeled only as an array even though RN also accepts a single value. -
[P2]ImageBackgroundnarrows its callback prop in ImageBackground.res. RN exposesimageRef?(image: Image): void, but the binding models it asimageRef?: Image.ref, which is not the same API shape. -
[P2]ScrollViewis narrower than RN in ScrollView.res.keyboardShouldPersistTapsomits the legacy boolean forms RN still types;StickyHeaderComponentis typed as a rendered element instead of the component/element union RN uses elsewhere; and many callback/render prop positions are narrower than the RN TS surface. -
[P2]VirtualizedListis materially narrower than RN in VirtualizedList.res.renderItemdoes not expose the fullseparatorsAPI (updatePropsis missing), list header/footer/empty components are narrowed tounit => React.elementinstead of component/element unions,renderScrollComponentomits its props parameter, andkeyExtractoris required even though RN makes it optional. -
[P2]FlatListinherits theVirtualizedListnarrowing and also misses public props RN 0.81 types directly in FlatList.res, includinglegacyImplementationand Android’s richerfadingEdgeLengthshape. -
[P2]Animatedconstructors and helpers are still behind the RN 0.81 typings in Animated.res.Value.create,ValueXY.create, andColor.createomit the optional config parameter;ValueXY.createcannot accept animated axes;parallelandeventrequire config objects RN makes optional;createAnimatedComponentomits its optionaloptions; and animated nodes do not exposehasListeners().
Notes
- Deprecated but still-exported RN 0.81 APIs such as
Clipboard,ProgressBarAndroid, andSafeAreaVieware present in this package. I did not count deprecation by itself as a finding when the binding shape still tracks RN’s public surface closely enough. - Helper modules such as
Color,Style,Event,EventSubscription, andPackagerwere only checked insofar as they affect the exposed RN bindings. This review is focused on the public React Native-facing contract of the package.
Sources
- react-native 0.81
types/index.d.ts - react-native 0.81
index.js - Animated.d.ts
- useAnimatedValue.d.ts
- AccessibilityInfo.d.ts
- ActionSheetIOS.d.ts
- Alert.d.ts
- AppRegistry.d.ts
- AppState.d.ts
- Appearance.d.ts
- BackHandler.d.ts
- Button.d.ts
- Clipboard.d.ts
- DevSettings.d.ts
- Dimensions.d.ts
- DrawerLayoutAndroid.d.ts
- EventEmitter.d.ts
- FlatList.d.ts
- Image.d.ts
- InputAccessoryView.d.ts
- Keyboard.d.ts
- KeyboardAvoidingView.d.ts
- LayoutAnimation.d.ts
- Linking.d.ts
- LogBox.d.ts
- Modal.d.ts
- NativeEventEmitter.d.ts
- PermissionsAndroid.d.ts
- Platform.d.ts
- Pressable.d.ts
- ProgressBarAndroid.d.ts
- ReactNativeTypes.d.ts
- RefreshControl.d.ts
- ScrollView.d.ts
- SectionList.d.ts
- Settings.d.ts
- Share.d.ts
- StatusBar.d.ts
- Switch.d.ts
- Text.d.ts
- TextInput.d.ts
- ToastAndroid.d.ts
- TouchableHighlight.d.ts
- TouchableNativeFeedback.d.ts
- TouchableOpacity.d.ts
- TouchableWithoutFeedback.d.ts
- UIManager.d.ts
- @react-native/virtualized-lists
VirtualizedList.d.ts - ViewPropTypes.d.ts