mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Fix TS exactOptionalPropertyTypes compatibility for generated types (#57628)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57628 NOTE: Patches over a `flow-api-translator` bug, which I'll fix upstream later. We need to pick this to `0.87-stable` to resolve user integration issues. **Context** TypeScript's `exactOptionalPropertyTypes` flag (strict mode) creates a distinction between `foo?: T` and `foo?: T | undefined`. ```js // Flow's semantics interface Props { onRefresh?: () => void; } const a: Props = { onRefresh: undefined }; // ✅ ok ``` ```ts // TypeScript with exactOptionalPropertyTypes: true (i.e. strict mode) interface Props { onRefresh?: () => void; } const a: Props = { onRefresh: undefined }; // ❌ error interface PropsFixed { onRefresh?: (() => void) | undefined; } const b: PropsFixed = { onRefresh: undefined }; // ✅ ok ``` With this added strictness in TypeScript, our generated types via `flow-api-translator` could create downstream type incompatibility in apps. **This diff** Patches the above issue in React Native's Flow → TS `types_generated/` pipeline. We transform all instances to the wider `foo?: T | undefined` format, for maximum compatibility. **Notes** `foo?: T [| undefined]` **remains stripped** in the API snapshot (existing transform with the aim of a concise format). There is a net, nonfunctional snapshot diff around function members, which (as a positive result) are re-ordered. Changelog: [General][Fixed] - **Strict TypeScript API**: Optional property types are now widened to explicitly include `| undefined` for `exactOptionalPropertyTypes` compatibility Reviewed By: cipolleschi Differential Revision: D113030161 fbshipit-source-id: 3ab005edab6b80b18fbb9ae7125ba56e3bd94195
This commit is contained in:
committed by
meta-codesync[bot]
parent
fcac53fe87
commit
0fc76bb527
+145
-145
@@ -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<<c43c7ab238b80e42e8e8f17f2ff5cb47>>
|
||||
* @generated SignedSource<<d895833bed3d3c274a6647773deaa023>>
|
||||
*
|
||||
* This file was generated by scripts/js-api/build-types/index.js.
|
||||
*/
|
||||
@@ -1650,10 +1650,10 @@ declare interface ButtonProps {
|
||||
readonly nextFocusRight?: number
|
||||
readonly nextFocusUp?: number
|
||||
readonly onAccessibilityAction?: (event: AccessibilityActionEvent) => unknown
|
||||
readonly onPress?: (event?: GestureResponderEvent) => unknown
|
||||
readonly testID?: string
|
||||
readonly title: string
|
||||
readonly touchSoundDisabled?: boolean
|
||||
readonly onPress?: (event?: GestureResponderEvent) => unknown
|
||||
}
|
||||
declare function cancelHeadlessTask(taskId: number, taskKey: string): void
|
||||
declare type Category = string
|
||||
@@ -1680,9 +1680,9 @@ declare type CellRendererProps<ItemT> = {
|
||||
readonly children: React.ReactNode
|
||||
readonly index: number
|
||||
readonly item: ItemT
|
||||
readonly style: StyleProp<ViewStyle>
|
||||
readonly onFocusCapture?: (event: FocusEvent) => void
|
||||
readonly onLayout?: (event: LayoutChangeEvent) => void
|
||||
readonly style: StyleProp<ViewStyle>
|
||||
}
|
||||
declare class CellRenderMask {
|
||||
addCells(cells: { first: number; last: number }): void
|
||||
@@ -2600,12 +2600,12 @@ declare type InterpolationConfigType<
|
||||
OutputT extends InterpolationConfigSupportedOutputType,
|
||||
> = Readonly<
|
||||
AnimatedNodeConfig & {
|
||||
easing?: (input: number) => number
|
||||
extrapolate?: ExtrapolateType
|
||||
extrapolateLeft?: ExtrapolateType
|
||||
extrapolateRight?: ExtrapolateType
|
||||
inputRange: ReadonlyArray<number>
|
||||
outputRange: ReadonlyArray<OutputT>
|
||||
easing?: (input: number) => number
|
||||
}
|
||||
>
|
||||
declare type IOSKeyboardEvent = Readonly<
|
||||
@@ -3249,6 +3249,14 @@ declare type OptionalFlatListProps<ItemT> = {
|
||||
end: number
|
||||
start: number
|
||||
}
|
||||
getItemLayout?: (
|
||||
data: Readonly<ArrayLike<ItemT>> | undefined,
|
||||
index: number,
|
||||
) => {
|
||||
index: number
|
||||
length: number
|
||||
offset: number
|
||||
}
|
||||
horizontal?: boolean
|
||||
initialNumToRender?: number
|
||||
initialScrollIndex?: number
|
||||
@@ -3258,14 +3266,6 @@ declare type OptionalFlatListProps<ItemT> = {
|
||||
removeClippedSubviews?: boolean
|
||||
renderItem?: ListRenderItem<ItemT>
|
||||
strictMode?: boolean
|
||||
getItemLayout?: (
|
||||
data: Readonly<ArrayLike<ItemT>> | undefined,
|
||||
index: number,
|
||||
) => {
|
||||
index: number
|
||||
length: number
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
declare type OptionalPlatformSelectSpec<T> = { [key in PlatformOSType]?: T }
|
||||
declare type OptionalSectionListProps<ItemT, SectionT = DefaultSectionT> = {
|
||||
@@ -3282,6 +3282,14 @@ declare type OptionalVirtualizedListProps = {
|
||||
debug?: boolean
|
||||
disableVirtualization?: boolean
|
||||
extraData?: any
|
||||
getItemLayout?: (
|
||||
data: any,
|
||||
index: number,
|
||||
) => {
|
||||
index: number
|
||||
length: number
|
||||
offset: number
|
||||
}
|
||||
horizontal?: boolean
|
||||
initialNumToRender?: number
|
||||
initialScrollIndex?: number
|
||||
@@ -3315,29 +3323,17 @@ declare type OptionalVirtualizedListProps = {
|
||||
refreshing?: boolean
|
||||
removeClippedSubviews?: boolean
|
||||
renderItem?: ListRenderItem<Item>
|
||||
renderScrollComponent?: (props: ScrollViewProps) => React.JSX.Element
|
||||
updateCellsBatchingPeriod?: number
|
||||
viewabilityConfig?: ViewabilityConfig
|
||||
viewabilityConfigCallbackPairs?: Array<ViewabilityConfigCallbackPair>
|
||||
windowSize?: number
|
||||
getItemLayout?: (
|
||||
data: any,
|
||||
index: number,
|
||||
) => {
|
||||
index: number
|
||||
length: number
|
||||
offset: number
|
||||
}
|
||||
renderScrollComponent?: (props: ScrollViewProps) => React.JSX.Element
|
||||
}
|
||||
declare type OptionalVirtualizedSectionListProps<
|
||||
ItemT,
|
||||
SectionT = DefaultVirtualizedSectionT,
|
||||
> = {
|
||||
onEndReached?: ($$PARAM_0$$: { distanceFromEnd: number }) => void
|
||||
renderSectionFooter?: (info: { section: SectionT }) => null | React.ReactNode
|
||||
renderSectionHeader?: (info: { section: SectionT }) => null | React.ReactNode
|
||||
SectionSeparatorComponent?: React.ComponentType<any>
|
||||
stickySectionHeadersEnabled?: boolean
|
||||
renderItem?: (info: {
|
||||
index: number
|
||||
item: ItemT
|
||||
@@ -3348,6 +3344,10 @@ declare type OptionalVirtualizedSectionListProps<
|
||||
updateProps: (select: "leading" | "trailing", newProps: Object) => void
|
||||
}
|
||||
}) => null | React.ReactNode
|
||||
renderSectionFooter?: (info: { section: SectionT }) => null | React.ReactNode
|
||||
renderSectionHeader?: (info: { section: SectionT }) => null | React.ReactNode
|
||||
SectionSeparatorComponent?: React.ComponentType<any>
|
||||
stickySectionHeadersEnabled?: boolean
|
||||
}
|
||||
declare type OrientationChangeEvent = {
|
||||
readonly orientation: "landscape" | "portrait"
|
||||
@@ -3577,13 +3577,13 @@ declare type PressabilityConfig = {
|
||||
readonly pressRectOffset?: RectOrSize
|
||||
}
|
||||
declare type PressabilityEventHandlers = {
|
||||
readonly onBlur: (event: BlurEvent) => void
|
||||
readonly onClick: (event: GestureResponderEvent) => void
|
||||
readonly onFocus: (event: FocusEvent) => void
|
||||
readonly onMouseEnter?: (event: MouseEvent) => void
|
||||
readonly onMouseLeave?: (event: MouseEvent) => void
|
||||
readonly onPointerEnter?: (event: PointerEvent) => void
|
||||
readonly onPointerLeave?: (event: PointerEvent) => void
|
||||
readonly onBlur: (event: BlurEvent) => void
|
||||
readonly onClick: (event: GestureResponderEvent) => void
|
||||
readonly onFocus: (event: FocusEvent) => void
|
||||
readonly onResponderGrant: (event: GestureResponderEvent) => boolean | void
|
||||
readonly onResponderMove: (event: GestureResponderEvent) => void
|
||||
readonly onResponderRelease: (event: GestureResponderEvent) => void
|
||||
@@ -4229,6 +4229,14 @@ declare type ScrollViewBaseProps = {
|
||||
readonly autoscrollToTopThreshold?: number
|
||||
readonly minIndexForVisible: number
|
||||
}
|
||||
readonly onContentSizeChange?: (
|
||||
contentWidth: number,
|
||||
contentHeight: number,
|
||||
) => void
|
||||
readonly onKeyboardDidHide?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardDidShow?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardWillHide?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardWillShow?: (event: KeyboardEvent) => void
|
||||
readonly onMomentumScrollBegin?: (event: ScrollEvent) => void
|
||||
readonly onMomentumScrollEnd?: (event: ScrollEvent) => void
|
||||
readonly onScroll?: (event: ScrollEvent) => void
|
||||
@@ -4249,14 +4257,6 @@ declare type ScrollViewBaseProps = {
|
||||
readonly StickyHeaderComponent?: StickyHeaderComponentType
|
||||
readonly stickyHeaderHiddenOnScroll?: boolean
|
||||
readonly stickyHeaderIndices?: ReadonlyArray<number>
|
||||
readonly onContentSizeChange?: (
|
||||
contentWidth: number,
|
||||
contentHeight: number,
|
||||
) => void
|
||||
readonly onKeyboardDidHide?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardDidShow?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardWillHide?: (event: KeyboardEvent) => void
|
||||
readonly onKeyboardWillShow?: (event: KeyboardEvent) => void
|
||||
}
|
||||
declare type ScrollViewComponentStatics = {
|
||||
readonly Context: typeof $$ScrollViewContext
|
||||
@@ -4329,13 +4329,13 @@ declare type ScrollViewPropsIOS = {
|
||||
readonly indicatorStyle?: "black" | "default" | "white"
|
||||
readonly maximumZoomScale?: number
|
||||
readonly minimumZoomScale?: number
|
||||
readonly onScrollToTop?: (event: ScrollEvent) => void
|
||||
readonly pinchGestureEnabled?: boolean
|
||||
readonly scrollIndicatorInsets?: EdgeInsetsProp
|
||||
readonly scrollsToTop?: boolean
|
||||
readonly scrollToOverflowEnabled?: boolean
|
||||
readonly showsHorizontalScrollIndicator?: boolean
|
||||
readonly zoomScale?: number
|
||||
readonly onScrollToTop?: (event: ScrollEvent) => void
|
||||
}
|
||||
declare interface ScrollViewScrollToOptions {
|
||||
animated?: boolean
|
||||
@@ -4359,6 +4359,10 @@ declare type SectionBase<
|
||||
data: ReadonlyArray<SectionItemT>
|
||||
ItemSeparatorComponent?: React.ComponentType<any> | React.JSX.Element
|
||||
key?: string
|
||||
keyExtractor?: (
|
||||
item: SectionItemT | undefined,
|
||||
index?: number | undefined,
|
||||
) => string
|
||||
renderItem?: (info: {
|
||||
index: number
|
||||
item: SectionItemT
|
||||
@@ -4369,10 +4373,6 @@ declare type SectionBase<
|
||||
updateProps: (select: "leading" | "trailing", newProps: Object) => void
|
||||
}
|
||||
}) => null | React.JSX.Element
|
||||
keyExtractor?: (
|
||||
item: SectionItemT | undefined,
|
||||
index?: number | undefined,
|
||||
) => string
|
||||
}
|
||||
declare class SectionList<
|
||||
ItemT = any,
|
||||
@@ -4504,6 +4504,17 @@ declare type ShareOptions = {
|
||||
}
|
||||
declare interface Spec extends TurboModule {
|
||||
readonly blur?: (reactTag: number) => void
|
||||
readonly focus?: (reactTag: number) => void
|
||||
readonly getConstantsForViewManager?: (
|
||||
viewManagerName: string,
|
||||
) => Object | undefined
|
||||
readonly getDefaultEventTypes?: () => Array<string>
|
||||
readonly lazilyLoadView?: (name: string) => Object
|
||||
readonly sendAccessibilityEvent?: (
|
||||
reactTag: number,
|
||||
eventType: number,
|
||||
) => void
|
||||
readonly setLayoutAnimationEnabledExperimental?: (enabled: boolean) => void
|
||||
readonly clearJSResponder: () => void
|
||||
readonly configureNextLayoutAnimation: (
|
||||
config: Object,
|
||||
@@ -4532,13 +4543,7 @@ declare interface Spec extends TurboModule {
|
||||
height: number,
|
||||
) => void,
|
||||
) => void
|
||||
readonly focus?: (reactTag: number) => void
|
||||
readonly getConstants: () => Object
|
||||
readonly getConstantsForViewManager?: (
|
||||
viewManagerName: string,
|
||||
) => Object | undefined
|
||||
readonly getDefaultEventTypes?: () => Array<string>
|
||||
readonly lazilyLoadView?: (name: string) => Object
|
||||
readonly manageChildren: (
|
||||
containerTag: number,
|
||||
moveFromIndices: Array<number>,
|
||||
@@ -4571,16 +4576,11 @@ declare interface Spec extends TurboModule {
|
||||
height: number,
|
||||
) => void,
|
||||
) => void
|
||||
readonly sendAccessibilityEvent?: (
|
||||
reactTag: number,
|
||||
eventType: number,
|
||||
) => void
|
||||
readonly setChildren: (containerTag: number, reactTags: Array<number>) => void
|
||||
readonly setJSResponder: (
|
||||
reactTag: number,
|
||||
blockNativeResponder: boolean,
|
||||
) => void
|
||||
readonly setLayoutAnimationEnabledExperimental?: (enabled: boolean) => void
|
||||
readonly updateView: (
|
||||
reactTag: number,
|
||||
viewName: string,
|
||||
@@ -5166,6 +5166,7 @@ declare type TimingAnimationConfig = Readonly<
|
||||
AnimationConfig & {
|
||||
delay?: number
|
||||
duration?: number
|
||||
easing?: (value: number) => number
|
||||
toValue:
|
||||
| AnimatedColor_default
|
||||
| AnimatedInterpolation_default<number>
|
||||
@@ -5177,7 +5178,6 @@ declare type TimingAnimationConfig = Readonly<
|
||||
readonly x: number
|
||||
readonly y: number
|
||||
}
|
||||
easing?: (value: number) => number
|
||||
}
|
||||
>
|
||||
declare type ToastAndroid = typeof ToastAndroid
|
||||
@@ -5699,22 +5699,22 @@ export {
|
||||
AccessibilityActionEvent, // a0d4daa0
|
||||
AccessibilityActionInfo, // db47a917
|
||||
AccessibilityInfo, // 23a3aa9b
|
||||
AccessibilityProps, // 21f32d3a
|
||||
AccessibilityProps, // eda80653
|
||||
AccessibilityRole, // f2f2e066
|
||||
AccessibilityState, // b0c2b3f7
|
||||
AccessibilityValue, // cf8bcb74
|
||||
ActionSheetIOS, // b558559e
|
||||
ActionSheetIOSOptions, // 1756eb5a
|
||||
ActivityIndicator, // 0f796809
|
||||
ActivityIndicator, // e43c68bb
|
||||
ActivityIndicatorInstance, // a82dd4e7
|
||||
ActivityIndicatorProps, // a232e3ff
|
||||
Alert, // 5bf12165
|
||||
ActivityIndicatorProps, // 619842eb
|
||||
Alert, // a398a509
|
||||
AlertButton, // bf1a3b60
|
||||
AlertButtonStyle, // ec9fb242
|
||||
AlertOptions, // a0cdac0f
|
||||
AlertOptions, // 8a116d2a
|
||||
AlertType, // 5ab91217
|
||||
AndroidKeyboardEvent, // e03becc8
|
||||
Animated, // 91a7b171
|
||||
Animated, // 50cbe576
|
||||
AppConfig, // 35c0ca70
|
||||
AppRegistry, // 1e8c5a00
|
||||
AppState, // 12012be5
|
||||
@@ -5728,9 +5728,9 @@ export {
|
||||
BackPressEventName, // 4620fb76
|
||||
BlurEvent, // 4ba4f941
|
||||
BoxShadowValue, // b679703f
|
||||
Button, // 2e36a068
|
||||
ButtonInstance, // 0a11787b
|
||||
ButtonProps, // 4a8a20e3
|
||||
Button, // bc8f6464
|
||||
ButtonInstance, // d94b4241
|
||||
ButtonProps, // 21c5780c
|
||||
Clipboard, // 41addb89
|
||||
CodegenTypes, // ab4986cc
|
||||
ColorSchemeName, // 6615edd6
|
||||
@@ -5748,9 +5748,9 @@ export {
|
||||
DimensionsPayload, // 653bc26c
|
||||
DisplayMetrics, // 1dc35cef
|
||||
DisplayMetricsAndroid, // 872e62eb
|
||||
DrawerLayoutAndroid, // a8ced056
|
||||
DrawerLayoutAndroid, // 7843b7b5
|
||||
DrawerLayoutAndroidInstance, // c0694352
|
||||
DrawerLayoutAndroidProps, // e9a67dd7
|
||||
DrawerLayoutAndroidProps, // 0c1d6155
|
||||
DrawerSlideEvent, // c4ab8fba
|
||||
DropShadowValue, // e9df2606
|
||||
DynamicColorIOS, // d96c228c
|
||||
@@ -5766,39 +5766,39 @@ export {
|
||||
EventSubscription, // b8d084aa
|
||||
ExtendedExceptionData, // 5a6ccf5a
|
||||
FilterFunction, // bf24c0e3
|
||||
FlatList, // 0f2531c9
|
||||
FlatListInstance, // f31d4744
|
||||
FlatListProps, // b8b5adf2
|
||||
FlatList, // e1b005c7
|
||||
FlatListInstance, // 2d1d8e45
|
||||
FlatListProps, // 94fa2dc7
|
||||
FocusEvent, // 850f1517
|
||||
FontVariant, // 7c7558bb
|
||||
GestureResponderEvent, // 14d3e77a
|
||||
GestureResponderHandlers, // c976c2ea
|
||||
GestureResponderHandlers, // b540de80
|
||||
HostComponent, // a611806a
|
||||
HostInstance, // f78dcaf8
|
||||
I18nManager, // f9870e00
|
||||
IEventEmitter, // fbef6131
|
||||
IOSKeyboardEvent, // e67bfe3a
|
||||
IgnorePattern, // ec6f6ece
|
||||
Image, // fba54a35
|
||||
ImageBackground, // 1543bae2
|
||||
ImageBackgroundInstance, // 610d9eed
|
||||
ImageBackgroundProps, // ceb153c3
|
||||
Image, // 87b793a4
|
||||
ImageBackground, // abfd6c1d
|
||||
ImageBackgroundInstance, // 50bc4cb3
|
||||
ImageBackgroundProps, // e04f173a
|
||||
ImageErrorEvent, // 978933f4
|
||||
ImageInstance, // 9a100753
|
||||
ImageLoadEvent, // 77f0b718
|
||||
ImageProgressEventIOS, // 445331a4
|
||||
ImageProps, // e8aecf89
|
||||
ImagePropsAndroid, // 9fd9bcbb
|
||||
ImagePropsBase, // f5535cef
|
||||
ImagePropsIOS, // 4a080668
|
||||
ImageProps, // c50cfe0d
|
||||
ImagePropsAndroid, // ee00e1d5
|
||||
ImagePropsBase, // fa3f8e21
|
||||
ImagePropsIOS, // 9e19c85d
|
||||
ImageRequireSource, // 681d683b
|
||||
ImageResizeMode, // d51106e2
|
||||
ImageResolvedAssetSource, // f3060931
|
||||
ImageSize, // 1c47cf88
|
||||
ImageSource, // 48c7f316
|
||||
ImageSourcePropType, // bfb5e5c6
|
||||
ImageSource, // ea31cf4a
|
||||
ImageSourcePropType, // f522e093
|
||||
ImageStyle, // 4b7c1906
|
||||
ImageURISource, // 016eb083
|
||||
ImageURISource, // 443d047c
|
||||
InputAccessoryView, // 9695d393
|
||||
InputAccessoryViewProps, // d94dc290
|
||||
InputModeOptions, // 4e8581b9
|
||||
@@ -5807,9 +5807,9 @@ export {
|
||||
KeyEvent, // 20fa4267
|
||||
KeyUpEvent, // 57f832c5
|
||||
Keyboard, // 49414c97
|
||||
KeyboardAvoidingView, // cf0307d2
|
||||
KeyboardAvoidingViewInstance, // c4ca43a7
|
||||
KeyboardAvoidingViewProps, // cf148633
|
||||
KeyboardAvoidingView, // fbf69b90
|
||||
KeyboardAvoidingViewInstance, // f6c63fc9
|
||||
KeyboardAvoidingViewProps, // 8609524c
|
||||
KeyboardEvent, // c3f895d4
|
||||
KeyboardEventEasing, // af4091c8
|
||||
KeyboardEventName, // 59299ad6
|
||||
@@ -5834,12 +5834,12 @@ export {
|
||||
MeasureInWindowOnSuccessCallback, // a285f598
|
||||
MeasureLayoutOnSuccessCallback, // 3592502a
|
||||
MeasureOnSuccessCallback, // 82824e59
|
||||
Modal, // 43f50013
|
||||
ModalBaseProps, // ac3931ad
|
||||
Modal, // 252d448a
|
||||
ModalBaseProps, // c294cc46
|
||||
ModalInstance, // d466ce77
|
||||
ModalProps, // 35252d68
|
||||
ModalProps, // 757e7cec
|
||||
ModalPropsAndroid, // 515fb173
|
||||
ModalPropsIOS, // 0e13cfcc
|
||||
ModalPropsIOS, // 664ecb7e
|
||||
ModeChangeEvent, // f64bf69d
|
||||
MouseEvent, // d1f889fd
|
||||
NativeAppEventEmitter, // 08d4c47d
|
||||
@@ -5857,10 +5857,10 @@ export {
|
||||
Networking, // bbc5be42
|
||||
OpaqueColorValue, // 25f3fa5b
|
||||
PackagerAsset, // d1c88cf4
|
||||
PanResponder, // f8f71cac
|
||||
PanResponderCallbacks, // 6d63e7be
|
||||
PanResponder, // e4df325a
|
||||
PanResponderCallbacks, // c3dafe87
|
||||
PanResponderGestureState, // 54baf558
|
||||
PanResponderInstance, // 69cebbe8
|
||||
PanResponderInstance, // 8ccc05bf
|
||||
Permission, // 08f1c82f
|
||||
PermissionStatus, // 4b7de97b
|
||||
PermissionsAndroid, // 8a0bc8d8
|
||||
@@ -5871,17 +5871,17 @@ export {
|
||||
PlatformSelectSpec, // 09ed7758
|
||||
PointValue, // 69db075f
|
||||
PointerEvent, // ff599afe
|
||||
PressabilityConfig, // faab5639
|
||||
PressabilityEventHandlers, // 0b910091
|
||||
Pressable, // f4911021
|
||||
PressabilityConfig, // fea539a5
|
||||
PressabilityEventHandlers, // c222648b
|
||||
Pressable, // 7008c06f
|
||||
PressableAndroidRippleConfig, // ee32eaca
|
||||
PressableInstance, // eebfe911
|
||||
PressableProps, // 95d57db2
|
||||
PressableProps, // d6bfa55b
|
||||
PressableStateCallbackType, // 9af36561
|
||||
ProcessedColorValue, // 33f74304
|
||||
ProgressBarAndroid, // 3625ddf0
|
||||
ProgressBarAndroid, // 2dd6dbfd
|
||||
ProgressBarAndroidInstance, // ab545ef1
|
||||
ProgressBarAndroidProps, // f20ebde5
|
||||
ProgressBarAndroidProps, // 07fa83a1
|
||||
PublicRootInstance, // 8040afd7
|
||||
PublicTextInstance, // 6937c7bf
|
||||
PushNotificationEventName, // 84e7e150
|
||||
@@ -5889,10 +5889,10 @@ export {
|
||||
PushNotificationPermissions, // c2e7ae4f
|
||||
Rationale, // 5df1b1c1
|
||||
ReactNativeVersion, // abd76827
|
||||
RefreshControl, // 5b3465d2
|
||||
RefreshControlInstance, // 8b4d078b
|
||||
RefreshControlProps, // f8883f9a
|
||||
RefreshControlPropsAndroid, // 99f64c97
|
||||
RefreshControl, // 947cb880
|
||||
RefreshControlInstance, // 55f1814a
|
||||
RefreshControlProps, // eb2b1cbe
|
||||
RefreshControlPropsAndroid, // 8ac931ca
|
||||
RefreshControlPropsIOS, // 72a36381
|
||||
Registry, // 6c39216d
|
||||
ResponderSyntheticEvent, // ebfa7f48
|
||||
@@ -5903,26 +5903,26 @@ export {
|
||||
RootViewStyleProvider, // 8792d506
|
||||
Runnable, // 594dd93a
|
||||
Runnables, // 4367c557
|
||||
SafeAreaView, // 47b1ede1
|
||||
SafeAreaView, // 9ce03f75
|
||||
SafeAreaViewInstance, // 21dba39c
|
||||
ScaledSize, // 07e417c7
|
||||
ScrollEvent, // d7abdd0a
|
||||
ScrollResponderType, // 079145bb
|
||||
ScrollResponderType, // ba188eae
|
||||
ScrollToLocationParamsType, // d7ecdad1
|
||||
ScrollView, // d7defbe2
|
||||
ScrollViewImperativeMethods, // d3ff1532
|
||||
ScrollViewInstance, // 1ba64600
|
||||
ScrollViewProps, // 9207390b
|
||||
ScrollViewPropsAndroid, // 44210553
|
||||
ScrollViewPropsIOS, // da991b9a
|
||||
ScrollView, // 066a8597
|
||||
ScrollViewImperativeMethods, // 904c66fd
|
||||
ScrollViewInstance, // ccf4f341
|
||||
ScrollViewProps, // b62913d1
|
||||
ScrollViewPropsAndroid, // 02f3df2e
|
||||
ScrollViewPropsIOS, // 807cb4f6
|
||||
ScrollViewScrollToOptions, // 3313411e
|
||||
SectionBase, // dca83594
|
||||
SectionList, // f483c886
|
||||
SectionListData, // e0d79987
|
||||
SectionListInstance, // 1b255509
|
||||
SectionListProps, // e06b9868
|
||||
SectionListRenderItem, // 466e3e87
|
||||
SectionListRenderItemInfo, // d809238e
|
||||
SectionBase, // 9f13db00
|
||||
SectionList, // ee3e7972
|
||||
SectionListData, // 1a4de01a
|
||||
SectionListInstance, // c9b991fe
|
||||
SectionListProps, // 0e933318
|
||||
SectionListRenderItem, // 715b2086
|
||||
SectionListRenderItemInfo, // 4a48a922
|
||||
Separators, // 6a45f7e3
|
||||
Settings, // 2be0c61e
|
||||
Share, // e4591b32
|
||||
@@ -5931,72 +5931,72 @@ export {
|
||||
ShareActionSheetIOSOptions, // eff574f5
|
||||
ShareContent, // 7c627896
|
||||
ShareOptions, // 800c3a4e
|
||||
StatusBar, // 81b4e92f
|
||||
StatusBar, // f95dbb76
|
||||
StatusBarAnimation, // 7fd047e6
|
||||
StatusBarInstance, // 4e03048c
|
||||
StatusBarProps, // bfedeab1
|
||||
StatusBarInstance, // 416e9640
|
||||
StatusBarProps, // c2a44d88
|
||||
StatusBarStyle, // 78f53eea
|
||||
StyleProp, // fa0e9b4a
|
||||
StyleSheet, // cdddb9ae
|
||||
StyleSheet, // e734acd4
|
||||
SubmitBehavior, // c4ddf490
|
||||
Switch, // b004beeb
|
||||
Switch, // f495bab3
|
||||
SwitchChangeEvent, // 899635b1
|
||||
SwitchInstance, // 3c50eec5
|
||||
SwitchProps, // ded81873
|
||||
SwitchProps, // cadfd0c4
|
||||
Systrace, // 626d178c
|
||||
TVViewPropsIOS, // 330ce7b5
|
||||
TargetedEvent, // 16e98910
|
||||
TaskProvider, // 266dedf2
|
||||
Text, // f792e51d
|
||||
Text, // 9ceaff08
|
||||
TextContentType, // 239b3ecc
|
||||
TextInput, // 4d0a088b
|
||||
TextInputAndroidProps, // 7109938a
|
||||
TextInput, // ce1e41ff
|
||||
TextInputAndroidProps, // 9ebbc103
|
||||
TextInputBlurEvent, // b77af40e
|
||||
TextInputChangeEvent, // f55eef98
|
||||
TextInputContentSizeChangeEvent, // a27cd32a
|
||||
TextInputEndEditingEvent, // e690b56b
|
||||
TextInputFocusEvent, // 19851a88
|
||||
TextInputIOSProps, // 0d05a855
|
||||
TextInputIOSProps, // fb3c9327
|
||||
TextInputInstance, // 5a0c0e0d
|
||||
TextInputKeyPressEvent, // 546c5d07
|
||||
TextInputProps, // a56c62a0
|
||||
TextInputProps, // c692f4de
|
||||
TextInputSelectionChangeEvent, // e58f2abc
|
||||
TextInputSubmitEditingEvent, // 6bcb2aa5
|
||||
TextInstance, // 05463a96
|
||||
TextLayoutEvent, // 3f54186f
|
||||
TextProps, // 58466ea1
|
||||
TextProps, // 93309fac
|
||||
TextStyle, // b62b8399
|
||||
ToastAndroid, // 88a8969a
|
||||
TouchableHighlight, // 20ba0199
|
||||
TouchableHighlight, // 3a6eaed4
|
||||
TouchableHighlightInstance, // b510c0eb
|
||||
TouchableHighlightProps, // 337a9164
|
||||
TouchableNativeFeedback, // c41fc93f
|
||||
TouchableNativeFeedbackInstance, // e7895451
|
||||
TouchableNativeFeedbackProps, // a645b648
|
||||
TouchableOpacity, // 74a1b2c6
|
||||
TouchableHighlightProps, // 00e100c4
|
||||
TouchableNativeFeedback, // fe739e82
|
||||
TouchableNativeFeedbackInstance, // 0877e3e4
|
||||
TouchableNativeFeedbackProps, // 1d0c2f30
|
||||
TouchableOpacity, // fe716ffc
|
||||
TouchableOpacityInstance, // b186055b
|
||||
TouchableOpacityProps, // 1d3512ce
|
||||
TouchableWithoutFeedback, // 61c63ada
|
||||
TouchableWithoutFeedbackProps, // f4d62822
|
||||
TouchableOpacityProps, // a3b32b69
|
||||
TouchableWithoutFeedback, // ed159ba7
|
||||
TouchableWithoutFeedbackProps, // e613ed05
|
||||
TransformsStyle, // 65e70f18
|
||||
TurboModule, // dfe29706
|
||||
TurboModuleRegistry, // 4ace6db2
|
||||
UIManager, // a1a7cc01
|
||||
UIManager, // afbcdf05
|
||||
UTFSequence, // ad625158
|
||||
Vibration, // 31e4bbf8
|
||||
View, // 443391a0
|
||||
View, // 3e72139a
|
||||
ViewInstance, // ffde5573
|
||||
ViewProps, // 013135a2
|
||||
ViewPropsAndroid, // 03c17367
|
||||
ViewProps, // 763271bb
|
||||
ViewPropsAndroid, // 55e81851
|
||||
ViewPropsIOS, // 58ee19bf
|
||||
ViewStyle, // e45056b1
|
||||
VirtualViewMode, // 6be59722
|
||||
VirtualizedList, // 68c7345e
|
||||
VirtualizedListInstance, // 423ee7c0
|
||||
VirtualizedListProps, // cc8bc4c9
|
||||
VirtualizedListProps, // f51f4a42
|
||||
VirtualizedSectionList, // 9fd9cd61
|
||||
VirtualizedSectionListInstance, // 12b706d5
|
||||
VirtualizedSectionListProps, // 12a58a4f
|
||||
VirtualizedSectionListProps, // 8210f30a
|
||||
WrapperComponentProvider, // 9ef54e61
|
||||
codegenNativeCommands, // 628a7c0a
|
||||
codegenNativeComponent, // 32a1bca6
|
||||
@@ -6004,10 +6004,10 @@ export {
|
||||
processColor, // 6e877698
|
||||
registerCallableModule, // 839c8cfe
|
||||
requireNativeComponent, // aa36a6dd
|
||||
useAnimatedColor, // e3511f81
|
||||
useAnimatedValue, // b18adb63
|
||||
useAnimatedValueXY, // c7ee2332
|
||||
useAnimatedColor, // a9dffd9f
|
||||
useAnimatedValue, // 25733d13
|
||||
useAnimatedValueXY, // 04c70878
|
||||
useColorScheme, // d585efdb
|
||||
usePressability, // 095343b5
|
||||
usePressability, // 782138ed
|
||||
useWindowDimensions, // bb4b683f
|
||||
}
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
const ensureUndefinedOnOptionalMembersVisitor = require('../ensureUndefinedOnOptionalMembers.js');
|
||||
const babel = require('@babel/core');
|
||||
|
||||
async function translate(code: string): Promise<string> {
|
||||
const result = await babel.transformAsync(code, {
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-typescript',
|
||||
ensureUndefinedOnOptionalMembersVisitor,
|
||||
],
|
||||
});
|
||||
|
||||
return result.code;
|
||||
}
|
||||
|
||||
describe('ensureUndefinedOnOptionalMembers', () => {
|
||||
test('should add undefined to optional type members', async () => {
|
||||
const code = `
|
||||
type Foo = {
|
||||
a?: number,
|
||||
'b-key'?: number | string,
|
||||
c?: () => void,
|
||||
d: boolean,
|
||||
e: string | undefined,
|
||||
f?: (() => void) | number,
|
||||
};
|
||||
`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = {
|
||||
a?: number | undefined;
|
||||
'b-key'?: number | string | undefined;
|
||||
c?: (() => void) | undefined;
|
||||
d: boolean;
|
||||
e: string | undefined;
|
||||
f?: (() => void) | number | undefined;
|
||||
};"
|
||||
`);
|
||||
});
|
||||
|
||||
test('should not add undefined when already present', async () => {
|
||||
const code = `
|
||||
type Foo = {
|
||||
a?: number | undefined,
|
||||
b?: undefined,
|
||||
};
|
||||
`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = {
|
||||
a?: number | undefined;
|
||||
b?: undefined;
|
||||
};"
|
||||
`);
|
||||
});
|
||||
});
|
||||
+16
@@ -42,4 +42,20 @@ describe('removeUndefinedFromOptionalMembers', () => {
|
||||
};"
|
||||
`);
|
||||
});
|
||||
|
||||
test('should unwrap the lone remaining constituent, dropping redundant parens', async () => {
|
||||
const code = `
|
||||
type Foo = {
|
||||
a?: (() => void) | undefined,
|
||||
b?: number | string | undefined,
|
||||
};
|
||||
`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = {
|
||||
a?: () => void;
|
||||
b?: number | string;
|
||||
};"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {PluginObj} from '@babel/core';
|
||||
|
||||
import * as t from '@babel/types';
|
||||
|
||||
/**
|
||||
* Ensures optional object members carry an explicit `| undefined`, e.g.
|
||||
* `foo?: number` becomes `foo?: number | undefined` (members that already
|
||||
* include `undefined` are left unchanged).
|
||||
*
|
||||
* This is the format required by TypeScript consumers building with
|
||||
* `exactOptionalPropertyTypes`, under which `foo?: T` and `foo?: T | undefined`
|
||||
* are distinct. It applies to the per-module generated types; the API snapshot
|
||||
* pipeline still strips it back via `removeUndefinedFromOptionalMembers`.
|
||||
*
|
||||
* This lives in React Native as a stopgap: flow-api-translator does not yet emit
|
||||
* this format, and the generated types cannot wait for its next release.
|
||||
*
|
||||
* The API snapshot resets this via `removeUndefinedFromOptionalMembers`, which
|
||||
* also unwraps the resulting single-constituent unions so function-valued
|
||||
* members remain bare function types for `sortProperties` to group.
|
||||
*/
|
||||
const visitor: PluginObj<unknown> = {
|
||||
visitor: {
|
||||
TSPropertySignature(path) {
|
||||
if (path.node.optional !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeAnnotation = path.node.typeAnnotation;
|
||||
if (!typeAnnotation || !t.isTSTypeAnnotation(typeAnnotation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actualTypeAnnotation = typeAnnotation.typeAnnotation;
|
||||
|
||||
if (t.isTSUndefinedKeyword(actualTypeAnnotation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isTSUnionType(actualTypeAnnotation)) {
|
||||
if (
|
||||
actualTypeAnnotation.types.some(type => t.isTSUndefinedKeyword(type))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
typeAnnotation.typeAnnotation = t.tsUnionType([
|
||||
...actualTypeAnnotation.types,
|
||||
t.tsUndefinedKeyword(),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
typeAnnotation.typeAnnotation = t.tsUnionType([
|
||||
actualTypeAnnotation,
|
||||
t.tsUndefinedKeyword(),
|
||||
]);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = visitor;
|
||||
+19
-3
@@ -29,11 +29,27 @@ const visitor: PluginObj<unknown> = {
|
||||
return;
|
||||
}
|
||||
|
||||
const newTypeAnnotation = t.cloneDeep(actualTypeAnnotation);
|
||||
newTypeAnnotation.types = newTypeAnnotation.types.filter(
|
||||
const remainingTypes = actualTypeAnnotation.types.filter(
|
||||
type => t.isTSUndefinedKeyword(type) === false,
|
||||
);
|
||||
typeAnnotation.typeAnnotation = newTypeAnnotation;
|
||||
if (remainingTypes.length === actualTypeAnnotation.types.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unwrap to the bare type when a single constituent remains, otherwise a
|
||||
// wrapper node survives that prints identically but breaks downstream
|
||||
// transforms (e.g. `sortProperties`) that key on the node type. The lone
|
||||
// constituent may be parenthesized (a function type inside a union needs
|
||||
// parens, e.g. `(() => void) | undefined`); those parens are redundant
|
||||
// once it is no longer part of a union.
|
||||
if (remainingTypes.length === 1) {
|
||||
const [remaining] = remainingTypes;
|
||||
typeAnnotation.typeAnnotation = t.isTSParenthesizedType(remaining)
|
||||
? remaining.typeAnnotation
|
||||
: remaining;
|
||||
} else {
|
||||
typeAnnotation.typeAnnotation = t.tsUnionType(remainingTypes);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -30,6 +30,7 @@ const preTransforms: Array<PreTransformFn> = [
|
||||
];
|
||||
const postTransforms = (filePath: string): Array<PluginObj<unknown>> => [
|
||||
require('./transforms/typescript/convertTypeAliasesToInterfaces'),
|
||||
require('./transforms/typescript/ensureUndefinedOnOptionalMembers'),
|
||||
require('./transforms/typescript/replaceProtectedConstructors'),
|
||||
require('./transforms/typescript/replaceDefaultExportName')(filePath),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user