From 51405567cf2d4468a070a2ac6af9207163802dde Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Sun, 21 Sep 2025 08:33:54 -0700 Subject: [PATCH 1/2] Simplify some RN types (#53868) Summary: This is a prep step to enable better Flow support for react 19 ref-as-prop. While it causes changes in the ReactNativeApi.d.ts snapshot, this diff simply inlines what these `React.ElementRef` evaluates into. Changelog: [Internal] Differential Revision: D82915646 --- .../Libraries/Image/ImageInjection.js | 9 +-- .../Libraries/Image/ImageTypes.flow.js | 10 +-- packages/react-native/ReactNativeApi.d.ts | 70 +++---------------- .../Lists/VirtualizedListContext.js | 11 ++- 4 files changed, 18 insertions(+), 82 deletions(-) diff --git a/packages/react-native/Libraries/Image/ImageInjection.js b/packages/react-native/Libraries/Image/ImageInjection.js index 561e5fa6c2d97d..60feb39992380f 100644 --- a/packages/react-native/Libraries/Image/ImageInjection.js +++ b/packages/react-native/Libraries/Image/ImageInjection.js @@ -8,11 +8,8 @@ * @format */ -import type { - AbstractImageAndroid, - AbstractImageIOS, - ImageType as ImageComponent, -} from './ImageTypes.flow'; +import type {HostInstance} from '../..'; +import type {AbstractImageAndroid, AbstractImageIOS} from './ImageTypes.flow'; import useMergeRefs from '../Utilities/useMergeRefs'; import * as React from 'react'; @@ -33,7 +30,7 @@ export function unstable_getImageComponentDecorator(): ?ImageComponentDecorator return injectedImageComponentDecorator; } -type ImageInstance = React.ElementRef; +type ImageInstance = HostInstance; type ImageAttachedCallback = ( imageInstance: ImageInstance, diff --git a/packages/react-native/Libraries/Image/ImageTypes.flow.js b/packages/react-native/Libraries/Image/ImageTypes.flow.js index 5de921b19d8cb9..87894e232bad7b 100644 --- a/packages/react-native/Libraries/Image/ImageTypes.flow.js +++ b/packages/react-native/Libraries/Image/ImageTypes.flow.js @@ -8,12 +8,11 @@ * @format */ +import type {HostInstance} from '../..'; import type {RootTag} from '../Types/RootTagTypes'; import type {ResolvedAssetSource} from './AssetSourceResolver'; import type {ImageProps as ImagePropsType} from './ImageProps'; import type {ImageSource} from './ImageSource'; -import typeof ImageViewNativeComponent from './ImageViewNativeComponent'; -import typeof TextInlineImageNativeComponent from './TextInlineImageNativeComponent'; import * as React from 'react'; @@ -67,17 +66,14 @@ type ImageComponentStaticsAndroid = $ReadOnly<{ }>; export type AbstractImageAndroid = component( - ref?: React.RefSetter< - | React.ElementRef - | React.ElementRef, - >, + ref?: React.RefSetter, ...props: ImagePropsType ); export type ImageAndroid = AbstractImageAndroid & ImageComponentStaticsAndroid; export type AbstractImageIOS = component( - ref?: React.RefSetter>, + ref?: React.RefSetter, ...props: ImagePropsType ); diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index b615999a22ed04..e1bb4297e729e5 100644 --- a/packages/react-native/ReactNativeApi.d.ts +++ b/packages/react-native/ReactNativeApi.d.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<377660a4dc9f8c721ebcd64f759637ac>> + * @generated SignedSource<<69d6b949e011e87bf0e3b81098fed285>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -77,7 +77,6 @@ declare const $$AnimatedView: AnimatedComponentType< React.ComponentRef > declare const $$flattenStyle: typeof flattenStyle_default -declare const $$ImageViewNativeComponent: typeof ImageViewNativeComponent_default declare const $$index: { keyExtractor: typeof keyExtractor get FillRateHelper(): FillRateHelperT @@ -92,7 +91,6 @@ declare const $$ProgressBarAndroidNativeComponent: HostComponent void } declare const Image: ImageType -declare const ImageViewNativeComponent_default: HostComponent declare const InputAccessoryView: typeof InputAccessoryView_default declare const InputAccessoryView_default: React.ComponentType declare const InteractionManager: typeof InteractionManagerStub_default @@ -465,7 +462,6 @@ declare const TextImpl_default: ( ref?: React.Ref }, ) => React.ReactNode -declare const TextInlineImage_default: HostComponent declare const TextInput: TextInputType declare const timing: typeof $$AnimatedImplementation.timing declare const timingImpl: ( @@ -1013,7 +1009,6 @@ declare type $$AnimatedSectionList = typeof $$AnimatedSectionList declare type $$AnimatedText = typeof $$AnimatedText declare type $$AnimatedView = typeof $$AnimatedView declare type $$flattenStyle = typeof $$flattenStyle -declare type $$ImageViewNativeComponent = typeof $$ImageViewNativeComponent declare type $$index = typeof $$index declare type $$NativeDeviceInfo = typeof $$NativeDeviceInfo declare type $$NativeDialogManagerAndroid = typeof $$NativeDialogManagerAndroid @@ -1022,8 +1017,6 @@ declare type $$ProgressBarAndroidNativeComponent = declare type $$ScrollViewContext = typeof $$ScrollViewContext declare type $$ScrollViewNativeComponent = typeof $$ScrollViewNativeComponent declare type $$SwitchNativeComponent = typeof $$SwitchNativeComponent -declare type $$TextInlineImageNativeComponent = - typeof $$TextInlineImageNativeComponent declare type $$ViewNativeComponent = typeof $$ViewNativeComponent declare type absoluteFill = typeof absoluteFill declare type absoluteFillObject = typeof absoluteFillObject @@ -1036,15 +1029,12 @@ declare type AbsoluteFillStyle = { } declare type AbstractImageAndroid = ( props: ImageProps & { - ref?: React.Ref< - | React.ComponentRef - | React.ComponentRef - > + ref?: React.Ref }, ) => React.ReactNode declare type AbstractImageIOS = ( props: ImageProps & { - ref?: React.Ref> + ref?: React.Ref }, ) => React.ReactNode declare type AccessibilityActionEvent = NativeSyntheticEvent<{ @@ -1899,7 +1889,7 @@ declare type ContentAvailable = 1 | null | void declare type Context = { readonly cellKey: string | undefined readonly horizontal: boolean | undefined - readonly getOutermostParentListRef: () => React.ComponentRef + readonly getOutermostParentListRef: () => VirtualizedList_default readonly getScrollMetrics: () => { contentLength: number dOffset: number @@ -1912,10 +1902,10 @@ declare type Context = { } readonly registerAsNestedChild: ($$PARAM_0$$: { cellKey: string - ref: React.ComponentRef + ref: VirtualizedList_default }) => void readonly unregisterAsNestedChild: ($$PARAM_0$$: { - ref: React.ComponentRef + ref: VirtualizedList_default }) => void } declare function counterEvent(eventName: EventName, value: number): void @@ -1940,7 +1930,6 @@ declare function createPublicTextInstance( ): ReadOnlyText_default declare type createPublicTextInstanceT = typeof createPublicTextInstance declare type CursorValue = "auto" | "pointer" -declare type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal declare type DataDetectorTypesType = | "address" | "all" @@ -2594,30 +2583,6 @@ declare type ImageErrorEvent = NativeSyntheticEvent< declare type ImageErrorEventData = { error: string } -declare type ImageHostComponentProps = Readonly< - ImageProps & - Omit & { - defaultSource?: (ImageSource | undefined) | (string | undefined) - headers?: { - [$$Key$$: string]: string - } - loadingIndicatorSrc?: string - shouldNotifyLoadEvents?: boolean - src?: - | ( - | ReadonlyArray< - | undefined - | { - readonly uri?: string - } - > - | undefined - ) - | (ResolvedAssetSource | undefined) - style?: DangerouslyImpreciseStyle | ImageStyleProp - tintColor?: ColorValue - } -> declare type ImageIOS = AbstractImageIOS & ImageComponentStaticsIOS declare type ImageLoadEvent = NativeSyntheticEvent> declare type ImageLoadEventData = { @@ -2732,7 +2697,6 @@ declare interface ImageURISource { readonly uri?: string readonly width?: number } -declare type ImageViewNativeComponent = typeof $$ImageViewNativeComponent declare type IndeterminateProgressBarAndroidStyleAttrProp = { indeterminate: true styleAttr: @@ -3971,21 +3935,6 @@ declare type RCTNetworkingEventDefinitions = { ] readonly didSendNetworkData: [[number, number, number]] } -declare type RCTTextInlineImageNativeProps = Readonly< - ViewProps & { - headers?: { - [$$Key$$: string]: string - } - resizeMode?: ImageResizeMode - src?: ReadonlyArray< - | undefined - | { - readonly uri?: string - } - > - tintColor?: ColorValue - } -> declare class ReactNativeDocument_default extends ReadOnlyNode_default { get childElementCount(): number get children(): HTMLCollection_default @@ -5161,8 +5110,6 @@ declare type TextContentType = declare type TextForwardRef = React.ComponentRef< typeof NativeText | typeof NativeVirtualText > -declare type TextInlineImageNativeComponent = - typeof $$TextInlineImageNativeComponent declare type TextInput = typeof TextInput declare type TextInputAndroidProps = { readonly cursorColor?: ColorValue @@ -5856,7 +5803,6 @@ declare type VirtualizedListProps = ScrollViewProps & RequiredVirtualizedListProps & OptionalVirtualizedListProps declare type VirtualizedListT = typeof VirtualizedList_default -declare type VirtualizedListT_2 = typeof VirtualizedList_default declare type VirtualizedListType = typeof $$index.VirtualizedList declare type VirtualizedSectionList = typeof VirtualizedSectionList declare type VirtualizedSectionListProps< @@ -6026,8 +5972,8 @@ export { IOSKeyboardEvent, // e67bfe3a IgnorePattern, // ec6f6ece Image, // 04474205 - ImageBackground, // e74abb26 - ImageBackgroundProps, // cadc2fba + ImageBackground, // 489b1c17 + ImageBackgroundProps, // 1b209e36 ImageErrorEvent, // b7b2ae63 ImageLoadEvent, // 5baae813 ImageProgressEventIOS, // adb35052 diff --git a/packages/virtualized-lists/Lists/VirtualizedListContext.js b/packages/virtualized-lists/Lists/VirtualizedListContext.js index 23fce825032cfe..f8065c3b5aa2f6 100644 --- a/packages/virtualized-lists/Lists/VirtualizedListContext.js +++ b/packages/virtualized-lists/Lists/VirtualizedListContext.js @@ -8,7 +8,7 @@ * @format */ -import typeof VirtualizedListT from './VirtualizedList'; +import type VirtualizedList from './VirtualizedList'; import * as React from 'react'; import {createContext, useContext, useMemo} from 'react'; @@ -26,12 +26,9 @@ type Context = $ReadOnly<{ zoomScale: number, }, horizontal: ?boolean, - getOutermostParentListRef: () => React.ElementRef, - registerAsNestedChild: ({ - cellKey: string, - ref: React.ElementRef, - }) => void, - unregisterAsNestedChild: ({ref: React.ElementRef}) => void, + getOutermostParentListRef: () => VirtualizedList, + registerAsNestedChild: ({cellKey: string, ref: VirtualizedList}) => void, + unregisterAsNestedChild: ({ref: VirtualizedList}) => void, }>; export const VirtualizedListContext: React.Context = From 8112576978a8c994517b1e872dfe8c96073ed771 Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Sun, 21 Sep 2025 08:33:54 -0700 Subject: [PATCH 2/2] Prepare createAnimatedComponent API for flow's upcoming better react 19 ref-as-prop support Summary: This is a prep step to enable better Flow support for react 19 ref-as-prop. While it causes changes in the ReactNativeApi.d.ts snapshot, it should preserve the existing type behavior, since in the TS version, the ref prop will be excluded anyways: https://github.com/facebook/react-native/blob/a4d43290c82e8ad93f03b304a78cdf0eaf41fba1/packages/react-native/ReactNativeApi.d.ts#L1434 Changelog: [Internal] Differential Revision: D82916014 --- .../Animated/createAnimatedComponent.js | 34 +++++++++++++------ packages/react-native/ReactNativeApi.d.ts | 22 ++++++++---- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/react-native/Libraries/Animated/createAnimatedComponent.js b/packages/react-native/Libraries/Animated/createAnimatedComponent.js index 345c1ac29ab3ea..f9970a1cc31756 100644 --- a/packages/react-native/Libraries/Animated/createAnimatedComponent.js +++ b/packages/react-native/Libraries/Animated/createAnimatedComponent.js @@ -63,17 +63,29 @@ type PassThroughProps = $ReadOnly<{ passthroughAnimatedPropExplicitValues?: ViewProps | null, }>; -export type AnimatedProps = { - [K in keyof Props]: K extends NonAnimatedProps - ? Props[K] - : WithAnimatedValue, -} & PassThroughProps; - -export type AnimatedBaseProps = { - [K in keyof Props]: K extends NonAnimatedProps - ? Props[K] - : WithAnimatedValue, -}; +type LooseOmit> = Pick< + O, + Exclude<$Keys, K>, +>; + +export type AnimatedProps = LooseOmit< + { + [K in keyof Props]: K extends NonAnimatedProps + ? Props[K] + : WithAnimatedValue, + }, + 'ref', +> & + PassThroughProps; + +export type AnimatedBaseProps = LooseOmit< + { + [K in keyof Props]: K extends NonAnimatedProps + ? Props[K] + : WithAnimatedValue, + }, + 'ref', +>; export type AnimatedComponentType = component( ref?: React.RefSetter, diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index e1bb4297e729e5..7771f1d4193c74 100644 --- a/packages/react-native/ReactNativeApi.d.ts +++ b/packages/react-native/ReactNativeApi.d.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<69d6b949e011e87bf0e3b81098fed285>> + * @generated SignedSource<<575e58047a8edf6bbc016768775a258f>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -1494,11 +1494,15 @@ declare class AnimatedNode_default { declare type AnimatedNodeConfig = { readonly debugID?: string } -declare type AnimatedProps = { - [K in keyof Props]: K extends NonAnimatedProps - ? Props[K] - : WithAnimatedValue -} & PassThroughProps +declare type AnimatedProps = LooseOmit< + { + [K in keyof Props]: K extends NonAnimatedProps + ? Props[K] + : WithAnimatedValue + }, + "ref" +> & + PassThroughProps declare type AnimatedScrollViewInstance = React.ComponentRef declare class AnimatedSubtraction_default extends AnimatedWithChildren_default { constructor( @@ -3075,6 +3079,10 @@ declare type LoopAnimationConfig = { iterations: number resetBeforeIteration?: boolean } +declare type LooseOmit = Pick< + O, + Exclude +> declare type MacOSPlatform = { OS: "macos" select: (spec: PlatformSelectSpec) => T @@ -5913,7 +5921,7 @@ export { AlertOptions, // a0cdac0f AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // 6ad7a14c + Animated, // 6b6a0b2e AppConfig, // ebddad4b AppRegistry, // 6cdee1d6 AppState, // f7097b1b