diff --git a/.flowconfig b/.flowconfig index 10d95a25dbe..dd9d94b5628 100644 --- a/.flowconfig +++ b/.flowconfig @@ -52,7 +52,7 @@ suppress_type=$FlowFixMeState suppress_type=$FlowFixMeEmpty experimental.array_literal_providers=true -inference_mode=constrain_writes +inference_mode=experimental.lti [lints] sketchy-null-number=warn diff --git a/.flowconfig.android b/.flowconfig.android index cfd396ab4fb..273933cb0ee 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -52,7 +52,7 @@ suppress_type=$FlowFixMeState suppress_type=$FlowFixMeEmpty experimental.array_literal_providers=true -inference_mode=constrain_writes +inference_mode=experimental.lti [lints] sketchy-null-number=warn diff --git a/Libraries/Animated/NativeAnimatedHelper.js b/Libraries/Animated/NativeAnimatedHelper.js index 7685f22999f..f24478627f0 100644 --- a/Libraries/Animated/NativeAnimatedHelper.js +++ b/Libraries/Animated/NativeAnimatedHelper.js @@ -248,6 +248,7 @@ const API = { } // $FlowFixMe API.queueOperation( + // $FlowFixMe[incompatible-call] nativeOps.startAnimatingNode, animationId, nodeTag, diff --git a/Libraries/Animated/bezier.js b/Libraries/Animated/bezier.js index f18cef48e2d..063bf12449f 100644 --- a/Libraries/Animated/bezier.js +++ b/Libraries/Animated/bezier.js @@ -105,7 +105,7 @@ export default function bezier( // Precompute samples table const sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) - : new Array(kSplineTableSize); + : new Array(kSplineTableSize); if (mX1 !== mY1 || mX2 !== mY2) { for (let i = 0; i < kSplineTableSize; ++i) { sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); diff --git a/Libraries/Animated/components/AnimatedScrollView.js b/Libraries/Animated/components/AnimatedScrollView.js index a3ba2d272ca..11a4162d6b5 100644 --- a/Libraries/Animated/components/AnimatedScrollView.js +++ b/Libraries/Animated/components/AnimatedScrollView.js @@ -67,12 +67,15 @@ const AnimatedScrollViewWithInvertedRefreshControl = React.forwardRef( // $FlowFixMe[unclear-type] Same Flow type as `refreshControl` in ScrollView refreshControl: React.Element, }, - forwardedRef, + forwardedRef: + | {current: Instance | null, ...} + | ((Instance | null) => mixed), ) => { // Split `props` into the animate-able props for the parent (RefreshControl) // and child (ScrollView). const {intermediatePropsForRefreshControl, intermediatePropsForScrollView} = useMemo(() => { + // $FlowFixMe[underconstrained-implicit-instantiation] const {outer, inner} = splitLayoutProps(flattenStyle(props.style)); return { intermediatePropsForRefreshControl: {style: outer}, diff --git a/Libraries/Animated/nodes/AnimatedInterpolation.js b/Libraries/Animated/nodes/AnimatedInterpolation.js index 62909423180..edd6286c06e 100644 --- a/Libraries/Animated/nodes/AnimatedInterpolation.js +++ b/Libraries/Animated/nodes/AnimatedInterpolation.js @@ -233,7 +233,8 @@ function createStringInterpolation( isColor ? // $FlowIgnoreMe[incompatible-call] output.components - : output.components.filter(c => typeof c === 'number'), + : // $FlowIgnoreMe[incompatible-call] + output.components.filter(c => typeof c === 'number'), ); const interpolations = numericComponents[0].map((_, i) => createNumericInterpolation({ diff --git a/Libraries/Animated/nodes/AnimatedStyle.js b/Libraries/Animated/nodes/AnimatedStyle.js index 31291968f16..e851b6031de 100644 --- a/Libraries/Animated/nodes/AnimatedStyle.js +++ b/Libraries/Animated/nodes/AnimatedStyle.js @@ -20,6 +20,7 @@ import AnimatedTransform from './AnimatedTransform'; import AnimatedWithChildren from './AnimatedWithChildren'; function createAnimatedStyle(inputStyle: any): Object { + // $FlowFixMe[underconstrained-implicit-instantiation] const style = flattenStyle(inputStyle); const animatedStyles: any = {}; for (const key in style) { @@ -36,6 +37,7 @@ function createAnimatedStyle(inputStyle: any): Object { } function createStyleWithAnimatedTransform(inputStyle: any): Object { + // $FlowFixMe[underconstrained-implicit-instantiation] let style = flattenStyle(inputStyle) || ({}: {[string]: any}); if (style.transform) { diff --git a/Libraries/Blob/URL.js b/Libraries/Blob/URL.js index 1cc3a9e8c4a..52e63b589f9 100644 --- a/Libraries/Blob/URL.js +++ b/Libraries/Blob/URL.js @@ -122,7 +122,7 @@ function validateBaseUrl(url: string) { export class URL { _url: string; - _searchParamsInstance = null; + _searchParamsInstance: ?URLSearchParams = null; static createObjectURL(blob: Blob): string { if (BLOB_URL_PREFIX === null) { @@ -220,6 +220,7 @@ export class URL { if (this._searchParamsInstance === null) { return this._url; } + // $FlowFixMe[incompatible-use] const instanceString = this._searchParamsInstance.toString(); const separator = this._url.indexOf('?') > -1 ? '&' : '?'; return this._url + separator + instanceString; diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index 0395706d260..2d674520c74 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -11,6 +11,7 @@ 'use strict'; +import type {TextStyleProp, ViewStyleProp} from '../StyleSheet/StyleSheet'; import type {PressEvent} from '../Types/CoreEventTypes'; import type {Button as ButtonType} from './Button.flow'; import type { @@ -310,8 +311,8 @@ class Button extends React.Component { accessibilityLanguage, onAccessibilityAction, } = this.props; - const buttonStyles = [styles.button]; - const textStyles = [styles.text]; + const buttonStyles: Array = [styles.button]; + const textStyles: Array = [styles.text]; if (color) { if (Platform.OS === 'ios') { textStyles.push({color: color}); diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index eab0ece03c6..e5f74ea627b 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -753,7 +753,7 @@ class ScrollView extends React.Component { _becameResponderWhileAnimating: boolean = false; _preventNegativeScrollOffset: ?boolean = null; - _animated = null; + _animated: ?boolean = null; _subscriptionKeyboardWillShow: ?EventSubscription = null; _subscriptionKeyboardWillHide: ?EventSubscription = null; @@ -1665,6 +1665,7 @@ class ScrollView extends React.Component { this.props.contentContainerStyle, ]; if (__DEV__ && this.props.style !== undefined) { + // $FlowFixMe[underconstrained-implicit-instantiation] const style = flattenStyle(this.props.style); const childLayoutProps = ['alignItems', 'justifyContent'].filter( prop => style && style[prop] !== undefined, @@ -1838,6 +1839,7 @@ class ScrollView extends React.Component { // AndroidSwipeRefreshLayout and use flex: 1 for the ScrollView. // Note: we should split props.style on the inner and outer props // however, the ScrollView still needs the baseStyle to be scrollable + // $FlowFixMe[underconstrained-implicit-instantiation] const {outer, inner} = splitLayoutProps(flattenStyle(props.style)); return React.cloneElement( refreshControl, diff --git a/Libraries/Components/Switch/Switch.js b/Libraries/Components/Switch/Switch.js index ea89d7aeee1..7197ded8b1e 100644 --- a/Libraries/Components/Switch/Switch.js +++ b/Libraries/Components/Switch/Switch.js @@ -157,7 +157,7 @@ const SwitchWithForwardedRef: React.AbstractComponent< const ref = useMergeRefs(nativeSwitchRef, forwardedRef); - const [native, setNative] = React.useState({value: null}); + const [native, setNative] = React.useState({value: (null: ?boolean)}); const handleChange = (event: SwitchChangeEvent) => { onChange?.(event); diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index bee049c8ee5..ec337de164e 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -1418,6 +1418,7 @@ function InternalTextInput(props: Props): React.Node { }; } + // $FlowFixMe[underconstrained-implicit-instantiation] let style = flattenStyle(props.style); if (Platform.OS === 'ios') { @@ -1628,6 +1629,7 @@ const ExportedForwardRef: React.AbstractComponent< }, forwardedRef: ReactRefSetter, ) { + // $FlowFixMe[underconstrained-implicit-instantiation] let style = flattenStyle(restProps.style); if (style?.verticalAlign != null) { diff --git a/Libraries/Components/Touchable/TouchableNativeFeedback.js b/Libraries/Components/Touchable/TouchableNativeFeedback.js index 9d21c4c4ee5..2571ddd0b7a 100644 --- a/Libraries/Components/Touchable/TouchableNativeFeedback.js +++ b/Libraries/Components/Touchable/TouchableNativeFeedback.js @@ -240,7 +240,7 @@ class TouchableNativeFeedback extends React.Component { render(): React.Node { const element = React.Children.only<$FlowFixMe>(this.props.children); - const children = [element.props.children]; + const children: Array = [element.props.children]; if (__DEV__) { if (element.type === View) { children.push( diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index cc18e8ecd0d..02dc8abd365 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -206,6 +206,7 @@ class TouchableOpacity extends React.Component { } _getChildStyleOpacityWithDefault(): number { + // $FlowFixMe[underconstrained-implicit-instantiation] const opacity = flattenStyle(this.props.style)?.opacity; return typeof opacity === 'number' ? opacity : 1; } @@ -301,7 +302,9 @@ class TouchableOpacity extends React.Component { this.state.pressability.configure(this._createPressabilityConfig()); if ( this.props.disabled !== prevProps.disabled || + // $FlowFixMe[underconstrained-implicit-instantiation] flattenStyle(prevProps.style)?.opacity !== + // $FlowFixMe[underconstrained-implicit-instantiation] flattenStyle(this.props.style)?.opacity ) { this._opacityInactive(250); diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index 1ffc217fda8..3963273175a 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -122,7 +122,7 @@ class TouchableWithoutFeedback extends React.Component { render(): React.Node { const element = React.Children.only<$FlowFixMe>(this.props.children); - const children = [element.props.children]; + const children: Array = [element.props.children]; const ariaLive = this.props['aria-live']; if (__DEV__) { diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index 86540410c83..0edf2e6820d 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -98,6 +98,7 @@ const View: React.AbstractComponent< }; } + // $FlowFixMe[underconstrained-implicit-instantiation] let style = flattenStyle(otherProps.style); const newPointerEvents = style?.pointerEvents || pointerEvents; diff --git a/Libraries/Core/Devtools/parseErrorStack.js b/Libraries/Core/Devtools/parseErrorStack.js index c85ddf05f13..f98a95cc4bf 100644 --- a/Libraries/Core/Devtools/parseErrorStack.js +++ b/Libraries/Core/Devtools/parseErrorStack.js @@ -48,7 +48,7 @@ function parseErrorStack(errorStack?: string): Array { ? errorStack : global.HermesInternal ? convertHermesStack(parseHermesStack(errorStack)) - : stacktraceParser.parse(errorStack).map(frame => ({ + : stacktraceParser.parse(errorStack).map((frame): StackFrame => ({ ...frame, column: frame.column != null ? frame.column - 1 : null, })); diff --git a/Libraries/Core/Timers/immediateShim.js b/Libraries/Core/Timers/immediateShim.js index 43915d6df16..29af6e56872 100644 --- a/Libraries/Core/Timers/immediateShim.js +++ b/Libraries/Core/Timers/immediateShim.js @@ -40,6 +40,7 @@ function setImmediate(callback: Function, ...args: any): number { clearedImmediates.delete(id); } + // $FlowFixMe[incompatible-call] global.queueMicrotask(() => { if (!clearedImmediates.has(id)) { callback.apply(undefined, args); diff --git a/Libraries/Core/setUpAlert.js b/Libraries/Core/setUpAlert.js index 85bf358c5bc..777f7f85fbe 100644 --- a/Libraries/Core/setUpAlert.js +++ b/Libraries/Core/setUpAlert.js @@ -15,7 +15,7 @@ * You can use this module directly, or just require InitializeCore. */ if (!global.alert) { - global.alert = function (text) { + global.alert = function (text: string) { // Require Alert on demand. Requiring it too early can lead to issues // with things like Platform not being fully initialized. require('../Alert/Alert').alert('Alert', '' + text); diff --git a/Libraries/Core/setUpDeveloperTools.js b/Libraries/Core/setUpDeveloperTools.js index 06f2079b878..4247d3bd947 100644 --- a/Libraries/Core/setUpDeveloperTools.js +++ b/Libraries/Core/setUpDeveloperTools.js @@ -56,7 +56,7 @@ if (__DEV__) { 'debug', ].forEach(level => { const originalFunction = console[level]; - console[level] = function (...args) { + console[level] = function (...args: $ReadOnlyArray) { HMRClient.log(level, args); originalFunction.apply(console, args); }; diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index ca219faa806..18a1c3fa9e8 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -152,10 +152,13 @@ const BaseImage = (props: ImagePropsType, forwardedRef) => { let style; let sources; if (Array.isArray(source)) { + // $FlowFixMe[underconstrained-implicit-instantiation] style = flattenStyle([styles.base, props.style]); sources = source; } else { + // $FlowFixMe[incompatible-type] const {width = props.width, height = props.height, uri} = source; + // $FlowFixMe[underconstrained-implicit-instantiation] style = flattenStyle([{width, height}, styles.base, props.style]); sources = [source]; if (uri === '') { diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 6f1d72fcb5a..ab1f443c633 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -114,10 +114,13 @@ const BaseImage = (props: ImagePropsType, forwardedRef) => { let sources; let style: ImageStyleProp; if (Array.isArray(source)) { + // $FlowFixMe[underconstrained-implicit-instantiation] style = flattenStyle([styles.base, props.style]) || {}; sources = source; } else { + // $FlowFixMe[incompatible-type] const {width = props.width, height = props.height, uri} = source; + // $FlowFixMe[underconstrained-implicit-instantiation] style = flattenStyle([{width, height}, styles.base, props.style]) || {}; sources = [source]; diff --git a/Libraries/Image/ImageBackground.js b/Libraries/Image/ImageBackground.js index 7beb733e703..7a51378ce44 100644 --- a/Libraries/Image/ImageBackground.js +++ b/Libraries/Image/ImageBackground.js @@ -76,6 +76,7 @@ class ImageBackground extends React.Component { ...props } = this.props; + // $FlowFixMe[underconstrained-implicit-instantiation] const flattenedStyle = flattenStyle(style); return ( { render(): React.Node { + // $FlowFixMe[underconstrained-implicit-instantiation] const style = flattenStyle(this.props.style) || {}; let margin = resolveBoxStyle('margin', style); let padding = resolveBoxStyle('padding', style); diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 52c736cc2b7..cf11abbfaf4 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -795,6 +795,7 @@ export default class VirtualizedList extends StateSafePureComponent< render(): React.Node { if (__DEV__) { + // $FlowFixMe[underconstrained-implicit-instantiation] const flatStyles = flattenStyle(this.props.contentContainerStyle); if (flatStyles != null && flatStyles.flexWrap === 'wrap') { console.warn( diff --git a/Libraries/Lists/VirtualizedListCellRenderer.js b/Libraries/Lists/VirtualizedListCellRenderer.js index e45e08283df..b16900d63b7 100644 --- a/Libraries/Lists/VirtualizedListCellRenderer.js +++ b/Libraries/Lists/VirtualizedListCellRenderer.js @@ -203,9 +203,13 @@ export default class CellRenderer extends React.Component< : this._onLayout; // NOTE: that when this is a sticky header, `onLayout` will get automatically extracted and // called explicitly by `ScrollViewStickyHeader`. - const itemSeparator = React.isValidElement(ItemSeparatorComponent) - ? ItemSeparatorComponent - : ItemSeparatorComponent && ( + const itemSeparator: React.Node = React.isValidElement( + ItemSeparatorComponent, + ) + ? // $FlowFixMe[incompatible-type] + ItemSeparatorComponent + : // $FlowFixMe[incompatible-type] + ItemSeparatorComponent && ( ); const cellStyle = inversionStyle diff --git a/Libraries/Lists/VirtualizedSectionList.js b/Libraries/Lists/VirtualizedSectionList.js index b1b3f8f4470..e4bf2fe58a0 100644 --- a/Libraries/Lists/VirtualizedSectionList.js +++ b/Libraries/Lists/VirtualizedSectionList.js @@ -530,6 +530,7 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node { React.useEffect(() => { setSelfHighlightCallback(cellKey, setSeparatorHighlighted); + // $FlowFixMe[incompatible-call] setSelfUpdatePropsCallback(cellKey, setSeparatorProps); return () => { diff --git a/Libraries/Lists/__flowtests__/FlatList-flowtest.js b/Libraries/Lists/__flowtests__/FlatList-flowtest.js index fb62a18ca4f..7b425087e3c 100644 --- a/Libraries/Lists/__flowtests__/FlatList-flowtest.js +++ b/Libraries/Lists/__flowtests__/FlatList-flowtest.js @@ -93,6 +93,7 @@ module.exports = { } + // $FlowExpectedError - bad title type number, should be string data={data} />, // EverythingIsFine diff --git a/Libraries/Lists/__tests__/VirtualizedSectionList-test.js b/Libraries/Lists/__tests__/VirtualizedSectionList-test.js index ca84e25f2e1..e0e861a26e8 100644 --- a/Libraries/Lists/__tests__/VirtualizedSectionList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedSectionList-test.js @@ -20,6 +20,7 @@ describe('VirtualizedSectionList', () => { const component = ReactTestRenderer.create( } @@ -60,6 +61,7 @@ describe('VirtualizedSectionList', () => { it('renders list with empty component', () => { const component = ReactTestRenderer.create( } getItem={(data, key) => data[key]} @@ -78,9 +80,10 @@ describe('VirtualizedSectionList', () => { ListFooterComponent={() =>