diff --git a/packages/react-native/Libraries/Animated/AnimatedExports.js b/packages/react-native/Libraries/Animated/AnimatedExports.js index 55940d81c39e..4cb32cf74e00 100644 --- a/packages/react-native/Libraries/Animated/AnimatedExports.js +++ b/packages/react-native/Libraries/Animated/AnimatedExports.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + import typeof AnimatedFlatList from './components/AnimatedFlatList'; import typeof AnimatedImage from './components/AnimatedImage'; import typeof AnimatedScrollView from './components/AnimatedScrollView'; @@ -27,7 +29,7 @@ export default { /** * FlatList and SectionList infer generic Type defined under their `data` and `section` props. */ - get FlatList(): AnimatedFlatList { + get FlatList(): AnimatedFlatList<> { return require('./components/AnimatedFlatList').default; }, /** @@ -47,7 +49,7 @@ export default { /** * FlatList and SectionList infer generic Type defined under their `data` and `section` props. */ - get SectionList(): AnimatedSectionList { + get SectionList(): AnimatedSectionList<> { return require('./components/AnimatedSectionList').default; }, /** diff --git a/packages/react-native/Libraries/Animated/AnimatedExports.js.flow b/packages/react-native/Libraries/Animated/AnimatedExports.js.flow index 7880f98f97af..6178617cec5b 100644 --- a/packages/react-native/Libraries/Animated/AnimatedExports.js.flow +++ b/packages/react-native/Libraries/Animated/AnimatedExports.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/Animated/createAnimatedComponent.js b/packages/react-native/Libraries/Animated/createAnimatedComponent.js index 922e95ec9f6c..0c1385c52417 100644 --- a/packages/react-native/Libraries/Animated/createAnimatedComponent.js +++ b/packages/react-native/Libraries/Animated/createAnimatedComponent.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -64,10 +64,10 @@ type PassThroughProps = Readonly<{ passthroughAnimatedPropExplicitValues?: ViewProps | null, }>; -type LooseOmit = Pick< - O, - Exclude, ->; +type LooseOmit< + O extends interface {}, + K extends string | number | symbol, +> = Pick>; export type AnimatedProps = LooseOmit< { @@ -94,7 +94,7 @@ export type AnimatedComponentType< > = component(ref?: React.RefSetter, ...AnimatedProps); export default function createAnimatedComponent< - TInstance extends React.ComponentType, + TInstance extends React.ComponentType, >( Component: TInstance, ): AnimatedComponentType< @@ -158,7 +158,9 @@ export function unstable_createAnimatedComponentWithAllowlist< }; AnimatedComponent.displayName = `Animated(${ - Component.displayName || 'Anonymous' + Component.displayName != null && Component.displayName !== '' + ? Component.displayName + : 'Anonymous' })`; return AnimatedComponent; diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedAddition.js b/packages/react-native/Libraries/Animated/nodes/AnimatedAddition.js index 91d686f5af3d..0f48c8072cfe 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedAddition.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedAddition.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -61,7 +61,11 @@ export default class AnimatedAddition extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: [number, number], + debugID: ?string, + } { return { type: 'addition', input: [this._a.__getNativeTag(), this._b.__getNativeTag()], diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js b/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js index 712c259d72ca..252814fd071d 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -90,9 +90,10 @@ function processColor( return null; } -function isRgbaValue(value: any): boolean { +function isRgbaValue(value: unknown): boolean { return ( - value && + value != null && + typeof value === 'object' && typeof value.r === 'number' && typeof value.g === 'number' && typeof value.b === 'number' && @@ -100,9 +101,10 @@ function isRgbaValue(value: any): boolean { ); } -function isRgbaAnimatedValue(value: any): boolean { +function isRgbaAnimatedValue(value: unknown): boolean { return ( - value && + value != null && + typeof value === 'object' && value.r instanceof AnimatedValue && value.g instanceof AnimatedValue && value.b instanceof AnimatedValue && @@ -166,7 +168,7 @@ export default class AnimatedColor extends AnimatedWithChildren { this.a = new AnimatedValue(initColor.a); } - if (config?.useNativeDriver) { + if (config?.useNativeDriver === true) { this.__makeNative(); } } @@ -325,7 +327,15 @@ export default class AnimatedColor extends AnimatedWithChildren { super.__makeNative(platformConfig); } - __getNativeConfig(): {...} { + __getNativeConfig(): { + type: string, + r: number, + g: number, + b: number, + a: number, + nativeColor: ?NativeColorValue, + debugID: ?string, + } { return { type: 'color', r: this.r.__getNativeTag(), diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedDiffClamp.js b/packages/react-native/Libraries/Animated/nodes/AnimatedDiffClamp.js index 94fef85aa0e1..29d0d170ad5c 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedDiffClamp.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedDiffClamp.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -68,7 +68,13 @@ export default class AnimatedDiffClamp extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: number, + min: number, + max: number, + debugID: ?string, + } { return { type: 'diffclamp', input: this._a.__getNativeTag(), diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedDivision.js b/packages/react-native/Libraries/Animated/nodes/AnimatedDivision.js index 6b73ff7d9931..ac8eba488ecf 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedDivision.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedDivision.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -77,7 +77,11 @@ export default class AnimatedDivision extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: [number, number], + debugID: ?string, + } { return { type: 'division', input: [this._a.__getNativeTag(), this._b.__getNativeTag()], diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedModulo.js b/packages/react-native/Libraries/Animated/nodes/AnimatedModulo.js index 32a698afbdac..91825c3dcf0f 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedModulo.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedModulo.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -55,7 +55,12 @@ export default class AnimatedModulo extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: number, + modulus: number, + debugID: ?string, + } { return { type: 'modulus', input: this._a.__getNativeTag(), diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedMultiplication.js b/packages/react-native/Libraries/Animated/nodes/AnimatedMultiplication.js index 93764f86c751..0411cb593ad3 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedMultiplication.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedMultiplication.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -60,7 +60,11 @@ export default class AnimatedMultiplication extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: [number, number], + debugID: ?string, + } { return { type: 'multiplication', input: [this._a.__getNativeTag(), this._b.__getNativeTag()], diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedObject.js b/packages/react-native/Libraries/Animated/nodes/AnimatedObject.js index 8f1793ec0472..6cbae410ddc1 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedObject.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedObject.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -64,7 +64,11 @@ function flatAnimatedNodes( } // Returns a copy of value with a transformation fn applied to any AnimatedNodes -function mapAnimatedNodes(value: any, fn: any => any, depth: number = 0): any { +function mapAnimatedNodes( + value: unknown, + fn: (node: AnimatedNode) => unknown, + depth: number = 0, +): unknown { if (depth >= MAX_DEPTH) { return value; } @@ -74,7 +78,7 @@ function mapAnimatedNodes(value: any, fn: any => any, depth: number = 0): any { } else if (Array.isArray(value)) { return value.map(element => mapAnimatedNodes(element, fn, depth + 1)); } else if (isPlainObject(value)) { - const result: {[string]: any} = {}; + const result: {[string]: unknown} = {}; const keys = Object.keys(value); for (let ii = 0, length = keys.length; ii < length; ii++) { const key = keys[ii]; @@ -115,13 +119,13 @@ export default class AnimatedObject extends AnimatedWithChildren { this._value = value; } - __getValue(): any { + __getValue(): unknown { return mapAnimatedNodes(this._value, node => { return node.__getValue(); }); } - __getValueWithStaticObject(staticObject: unknown): any { + __getValueWithStaticObject(staticObject: unknown): unknown { const nodes = this._nodes; let index = 0; // NOTE: We can depend on `this._value` and `staticObject` sharing a @@ -129,7 +133,7 @@ export default class AnimatedObject extends AnimatedWithChildren { return mapAnimatedNodes(staticObject, () => nodes[index++].__getValue()); } - __getAnimatedValue(): any { + __getAnimatedValue(): unknown { return mapAnimatedNodes(this._value, node => { return node.__getAnimatedValue(); }); @@ -162,7 +166,11 @@ export default class AnimatedObject extends AnimatedWithChildren { super.__makeNative(platformConfig); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + value: unknown, + debugID: ?string, + } { return { type: 'object', value: mapAnimatedNodes(this._value, node => { diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedSubtraction.js b/packages/react-native/Libraries/Animated/nodes/AnimatedSubtraction.js index 04181bda7b20..0b1d3f22c52c 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedSubtraction.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedSubtraction.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -61,7 +61,11 @@ export default class AnimatedSubtraction extends AnimatedWithChildren { super.__detach(); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + input: [number, number], + debugID: ?string, + } { return { type: 'subtraction', input: [this._a.__getNativeTag(), this._b.__getNativeTag()], diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedTracking.js b/packages/react-native/Libraries/Animated/nodes/AnimatedTracking.js index d50d2921e5b0..17229e30b3bb 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedTracking.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedTracking.js @@ -4,33 +4,40 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ 'use strict'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -import type {EndCallback} from '../animations/Animation'; +import type Animation from '../animations/Animation'; +import type {AnimationConfig, EndCallback} from '../animations/Animation'; import type {AnimatedNodeConfig} from './AnimatedNode'; import type AnimatedValue from './AnimatedValue'; import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import AnimatedNode from './AnimatedNode'; +type TrackingAnimationConfig = Readonly<{ + ...AnimationConfig, + toValue: AnimatedNode, + ... +}>; + export default class AnimatedTracking extends AnimatedNode { _value: AnimatedValue; _parent: AnimatedNode; _callback: ?EndCallback; - _animationConfig: Object; - _animationClass: any; + _animationConfig: TrackingAnimationConfig; + _animationClass: Class; _useNativeDriver: boolean; constructor( value: AnimatedValue, parent: AnimatedNode, - animationClass: any, - animationConfig: Object, + animationClass: Class, + animationConfig: TrackingAnimationConfig, callback?: ?EndCallback, config?: ?AnimatedNodeConfig, ) { @@ -52,7 +59,7 @@ export default class AnimatedTracking extends AnimatedNode { this._value.__makeNative(platformConfig); } - __getValue(): Object { + __getValue(): number { return this._parent.__getValue(); } @@ -79,13 +86,20 @@ export default class AnimatedTracking extends AnimatedNode { this._value.animate( new this._animationClass({ ...this._animationConfig, - toValue: (this._animationConfig.toValue as any).__getValue(), + toValue: this._animationConfig.toValue.__getValue(), }), this._callback, ); } - __getNativeConfig(): any { + __getNativeConfig(): { + type: string, + animationId: number, + animationConfig: Readonly<{platformConfig: ?PlatformConfig, ...}>, + toValue: number, + value: number, + debugID: ?string, + } { const animation = new this._animationClass({ ...this._animationConfig, // remove toValue from the config as it's a ref to Animated.Value diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js b/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js index 76dba2196f48..800f8dba0350 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -55,10 +55,12 @@ const NativeAnimatedAPI = NativeAnimatedHelper.API; * transform which can receive values from multiple parents. */ export function flushValue(rootNode: AnimatedNode): void { - const leaves = new Set<{update: () => void, ...}>(); + const leaves = new Set void}>(); function findAnimatedStyles(node: AnimatedNode) { - // $FlowFixMe[prop-missing] - if (typeof node.update === 'function') { + if ( + typeof (node as interface {update?: () => void}).update === 'function' + ) { + // $FlowFixMe[unclear-type] `update` is duck-typed on animated leaf nodes and not declared on AnimatedNode leaves.add(node as any); } else { node.__getChildren().forEach(findAnimatedStyles); @@ -138,7 +140,7 @@ export default class AnimatedValue extends AnimatedWithChildren { } } - addListener(callback: (value: any) => unknown): string { + addListener(callback: (value: {value: number}) => unknown): string { const id = super.addListener(callback); this._listenerCount++; if (this.__isNative) { @@ -371,7 +373,12 @@ export default class AnimatedValue extends AnimatedWithChildren { this.__callListeners(this.__getValue()); } - __getNativeConfig(): Object { + __getNativeConfig(): { + type: string, + value: number, + offset: number, + debugID: ?string, + } { return { type: 'value', value: this._value, diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedValueXY.js b/packages/react-native/Libraries/Animated/nodes/AnimatedValueXY.js index 0c008919c8b8..a2634798a856 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedValueXY.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedValueXY.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -52,18 +52,23 @@ export default class AnimatedValueXY extends AnimatedWithChildren { config?: ?AnimatedValueXYConfig, ) { super(config); - const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any` - if (typeof value.x === 'number' && typeof value.y === 'number') { - this.x = new AnimatedValue(value.x); - this.y = new AnimatedValue(value.y); + const value: { + readonly x: number | AnimatedValue, + readonly y: number | AnimatedValue, + ... + } = valueIn || {x: 0, y: 0}; + const {x, y} = value; + if (typeof x === 'number' && typeof y === 'number') { + this.x = new AnimatedValue(x); + this.y = new AnimatedValue(y); } else { invariant( - value.x instanceof AnimatedValue && value.y instanceof AnimatedValue, + x instanceof AnimatedValue && y instanceof AnimatedValue, 'AnimatedValueXY must be initialized with an object of numbers or ' + 'AnimatedValues.', ); - this.x = value.x; - this.y = value.y; + this.x = x; + this.y = y; } this._listeners = {}; if (config && config.useNativeDriver) { @@ -164,7 +169,7 @@ export default class AnimatedValueXY extends AnimatedWithChildren { */ addListener(callback: ValueXYListenerCallback): string { const id = String(_uniqueId++); - const jointCallback = ({value: number}: any) => { + const jointCallback = () => { callback(this.__getValue()); }; this._listeners[id] = { diff --git a/packages/react-native/Libraries/Blob/File.js b/packages/react-native/Libraries/Blob/File.js index 0783d1c503b6..ccbd83dba703 100644 --- a/packages/react-native/Libraries/Blob/File.js +++ b/packages/react-native/Libraries/Blob/File.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + 'use strict'; import type {BlobOptions} from './BlobTypes'; diff --git a/packages/react-native/Libraries/Blob/FileReader.js b/packages/react-native/Libraries/Blob/FileReader.js index 98e7f8c9da15..07c5744d9c29 100644 --- a/packages/react-native/Libraries/Blob/FileReader.js +++ b/packages/react-native/Libraries/Blob/FileReader.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + import type {EventCallback} from '../../src/private/webapis/dom/events/EventTarget'; import type Blob from './Blob'; diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index f4f879a51214..8386cc6d979d 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + import type Blob from './Blob'; import NativeBlobModule from './NativeBlobModule'; @@ -79,7 +81,7 @@ export class URL { // $FlowFixMe[missing-local-annot] constructor(url: string, base?: string | URL) { let baseUrl = null; - if (!base || validateBaseUrl(url)) { + if (base == null || base === '' || validateBaseUrl(url)) { this._url = url; if (this._url.includes('#')) { const split = this._url.split('#'); @@ -112,13 +114,14 @@ export class URL { if (baseUrl.endsWith('/')) { baseUrl = baseUrl.slice(0, baseUrl.length - 1); } - if (!url.startsWith('/')) { - url = `/${url}`; + let path = url; + if (!path.startsWith('/')) { + path = `/${path}`; } - if (baseUrl.endsWith(url)) { - url = ''; + if (baseUrl.endsWith(path)) { + path = ''; } - this._url = `${baseUrl}${url}`; + this._url = `${baseUrl}${path}`; } } diff --git a/packages/react-native/Libraries/Blob/URLSearchParams.js b/packages/react-native/Libraries/Blob/URLSearchParams.js index d325f7bb25a8..1cf3ef6b2f4e 100644 --- a/packages/react-native/Libraries/Blob/URLSearchParams.js +++ b/packages/react-native/Libraries/Blob/URLSearchParams.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + // Small subset from whatwg-url: https://github.com/jsdom/whatwg-url/tree/master/src // The reference code bloat comes from Unicode issues with URLs, so those won't work here. export class URLSearchParams { diff --git a/packages/react-native/Libraries/Blob/URLSearchParams.js.flow b/packages/react-native/Libraries/Blob/URLSearchParams.js.flow index df5b32557dda..fe7741a88d41 100644 --- a/packages/react-native/Libraries/Blob/URLSearchParams.js.flow +++ b/packages/react-native/Libraries/Blob/URLSearchParams.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 3200bb8afc56..f021d43aad26 100644 --- a/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -115,7 +115,7 @@ const ActivityIndicator: component( style, ...restProps }: { - ref?: any, + ref?: React.RefSetter, ...ActivityIndicatorProps, }) => { let sizeStyle; diff --git a/packages/react-native/Libraries/Components/Button.js b/packages/react-native/Libraries/Components/Button.js index c1bec4b65edf..7855575dbf80 100644 --- a/packages/react-native/Libraries/Components/Button.js +++ b/packages/react-native/Libraries/Components/Button.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -232,7 +232,7 @@ const Button: component( } = props; const buttonStyles: Array = [styles.button]; const textStyles: Array = [styles.text]; - if (color) { + if (color != null && color !== '' && color !== 0) { if (Platform.OS === 'ios') { textStyles.push({color: color}); } else { @@ -256,7 +256,7 @@ const Button: component( ? {..._accessibilityState, disabled} : _accessibilityState; - if (disabled) { + if (disabled === true) { buttonStyles.push(styles.buttonDisabled); textStyles.push(styles.textDisabled); } @@ -279,7 +279,9 @@ const Button: component( accessible={accessible} accessibilityActions={accessibilityActions} onAccessibilityAction={onAccessibilityAction} - accessibilityLabel={ariaLabel || accessibilityLabel} + accessibilityLabel={ + ariaLabel != null && ariaLabel !== '' ? ariaLabel : accessibilityLabel + } accessibilityHint={accessibilityHint} accessibilityLanguage={accessibilityLanguage} accessibilityRole="button" diff --git a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js index 77c72316cfe8..0ee0b92b667c 100644 --- a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +++ b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + import type { MeasureInWindowOnSuccessCallback, MeasureLayoutOnSuccessCallback, @@ -204,7 +206,7 @@ class DrawerLayoutAndroid ); } - setNativeProps(nativeProps: Object) { + setNativeProps(nativeProps: {...}) { nullthrows(this._nativeRef.current).setNativeProps(nativeProps); } } diff --git a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js index 5776fd4f500e..0bf8cca18b4d 100644 --- a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js +++ b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroidTypes.js b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroidTypes.js index c5b16a13e090..cbe137320123 100644 --- a/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroidTypes.js +++ b/packages/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroidTypes.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -127,7 +127,7 @@ export interface DrawerLayoutAndroidMethods { onSuccess: MeasureLayoutOnSuccessCallback, onFail?: () => void, ): void; - setNativeProps(nativeProps: Object): void; + setNativeProps(nativeProps: {...}): void; } export type DrawerLayoutAndroidInstance = DrawerLayoutAndroidMethods; diff --git a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js index 0cd2315373ae..bab23467263c 100644 --- a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js +++ b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -101,13 +101,25 @@ export type StatusBarProps = Readonly<{ type StackProps = { barStyle: ?{ - value: StatusBarProps['barStyle'], + value: StatusBarStyle, animated: boolean, }, hidden: ?{ value: boolean, animated: boolean, - transition: StatusBarProps['showHideTransition'], + transition: StatusBarAnimation, + }, +}; + +type ResolvedStackProps = { + barStyle: { + value: StatusBarStyle, + animated: boolean, + }, + hidden: { + value: boolean, + animated: boolean, + transition: StatusBarAnimation, }, }; @@ -126,13 +138,16 @@ function getAutoBarStyle(): 'light-content' | 'dark-content' { * barStyle to a concrete value. */ function mergePropsStack( - propsStack: Array, - defaultValues: Object, -): Object { - const merged: StackProps = propsStack.reduce( + propsStack: Array, + defaultValues: ResolvedStackProps, +): ResolvedStackProps { + const merged: ResolvedStackProps = propsStack.reduce( (prev, cur) => { for (const prop in cur) { + // $FlowFixMe[invalid-computed-prop] dynamic merge over the known StackProps keys if (cur[prop] != null) { + // $FlowFixMe[invalid-computed-prop] dynamic merge over the known StackProps keys + // $FlowFixMe[prop-missing] dynamic merge over the known StackProps keys prev[prop] = cur[prop]; } } @@ -141,7 +156,7 @@ function mergePropsStack( {...defaultValues}, ); - if (merged.barStyle?.value === 'auto') { + if (merged.barStyle.value === 'auto') { merged.barStyle = {...merged.barStyle, value: getAutoBarStyle()}; } @@ -224,10 +239,10 @@ function createStackEntry(props: StatusBarProps): StackProps { class StatusBar extends React.Component { static _propsStack: Array = []; - static _defaultProps: any = createStackEntry({ - barStyle: 'default', - hidden: false, - }); + static _defaultProps: ResolvedStackProps = { + barStyle: {value: 'default', animated: false}, + hidden: {value: false, animated: false, transition: 'fade'}, + }; // Timer for updating the native module values at the end of the frame. static _updateImmediate: ?number = null; @@ -235,7 +250,7 @@ class StatusBar extends React.Component { // The current merged values from the props stack. `barStyle.value` is stored // in its resolved form (never `'auto'`), so diff comparisons reflect what // was actually sent to the native module. - static _currentValues: ?StackProps = null; + static _currentValues: ?ResolvedStackProps = null; // Number of mounted `StatusBar` instances. Used to lazily subscribe to color // scheme changes only while at least one instance is on screen. @@ -264,10 +279,10 @@ class StatusBar extends React.Component { * changing the status bar hidden property. */ static setHidden(hidden: boolean, animation?: StatusBarAnimation) { - animation = animation || 'none'; + const resolvedAnimation = animation ?? 'none'; StatusBar._defaultProps.hidden.value = hidden; if (Platform.OS === 'ios') { - NativeStatusBarManagerIOS.setHidden(hidden, animation); + NativeStatusBarManagerIOS.setHidden(hidden, resolvedAnimation); } else if (Platform.OS === 'android') { NativeStatusBarManagerAndroid.setHidden(hidden); } @@ -279,11 +294,11 @@ class StatusBar extends React.Component { * @param animated Animate the style change. */ static setBarStyle(style: StatusBarStyle, animated?: boolean) { - animated = animated || false; + const resolvedAnimated = animated ?? false; StatusBar._defaultProps.barStyle.value = style; const resolvedStyle = style === 'auto' ? getAutoBarStyle() : style; if (Platform.OS === 'ios') { - NativeStatusBarManagerIOS.setStyle(resolvedStyle, animated); + NativeStatusBarManagerIOS.setStyle(resolvedStyle, resolvedAnimated); } else if (Platform.OS === 'android') { NativeStatusBarManagerAndroid.setStyle(resolvedStyle); } diff --git a/packages/react-native/Libraries/Components/Touchable/Touchable.js b/packages/react-native/Libraries/Components/Touchable/Touchable.js index 827477f98c5b..8c5605366426 100644 --- a/packages/react-native/Libraries/Components/Touchable/Touchable.js +++ b/packages/react-native/Libraries/Components/Touchable/Touchable.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -331,7 +331,7 @@ const TouchableMixinImpl = { */ /* $FlowFixMe[missing-this-annot] The 'this' type annotation(s) required by * Flow's LTI update could not be added via codemod */ - touchableHandleResponderTerminationRequest: function (): any { + touchableHandleResponderTerminationRequest: function (): boolean { return !this.props.rejectResponderTermination; }, @@ -340,7 +340,7 @@ const TouchableMixinImpl = { */ /* $FlowFixMe[missing-this-annot] The 'this' type annotation(s) required by * Flow's LTI update could not be added via codemod */ - touchableHandleStartShouldSetResponder: function (): any { + touchableHandleStartShouldSetResponder: function (): boolean { return !this.props.disabled; }, diff --git a/packages/react-native/Libraries/Core/Timers/immediateShim.js b/packages/react-native/Libraries/Core/Timers/immediateShim.js index 6e9534de1621..df84d573ed3f 100644 --- a/packages/react-native/Libraries/Core/Timers/immediateShim.js +++ b/packages/react-native/Libraries/Core/Timers/immediateShim.js @@ -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. * - * @flow + * @flow strict-local * @format * @deprecated */ @@ -22,7 +22,10 @@ const clearedImmediates: Set = new Set(); * @param {function} func Callback to be invoked before the end of the * current JavaScript execution loop. */ -export function setImmediate(callback: Function, ...args: any): number { +export function setImmediate>( + callback: (...args: TArgs) => unknown, + ...args: TArgs +): number { if (arguments.length < 1) { throw new TypeError( 'setImmediate must be called with at least one argument (a function to call)', @@ -41,7 +44,6 @@ export function setImmediate(callback: Function, ...args: any): number { clearedImmediates.delete(id); } - // $FlowFixMe[incompatible-type] global.queueMicrotask(() => { if (!clearedImmediates.has(id)) { callback.apply(undefined, args); diff --git a/packages/react-native/Libraries/Core/Timers/queueMicrotask.js b/packages/react-native/Libraries/Core/Timers/queueMicrotask.js index 34741aa1f838..efc8a3da277f 100644 --- a/packages/react-native/Libraries/Core/Timers/queueMicrotask.js +++ b/packages/react-native/Libraries/Core/Timers/queueMicrotask.js @@ -4,13 +4,13 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ 'use strict'; -let resolvedPromise; +let resolvedPromise: ?Promise; /** * Polyfill for the microtask queueing API defined by WHATWG HTML spec. @@ -19,7 +19,7 @@ let resolvedPromise; * The method must queue a microtask to invoke @param {function} callback, and * if the callback throws an exception, report the exception. */ -export default function queueMicrotask(callback: Function) { +export default function queueMicrotask(callback: () => unknown) { if (arguments.length < 1) { throw new TypeError( 'queueMicrotask must be called with at least one argument (a function to call)', @@ -30,7 +30,6 @@ export default function queueMicrotask(callback: Function) { } // Try to reuse a lazily allocated resolved promise from closure. - // $FlowFixMe[constant-condition] (resolvedPromise || (resolvedPromise = Promise.resolve())) .then(callback) .catch(error => diff --git a/packages/react-native/Libraries/EventEmitter/RCTEventEmitter.js b/packages/react-native/Libraries/EventEmitter/RCTEventEmitter.js index 069caedcb254..3e5bb8e66242 100644 --- a/packages/react-native/Libraries/EventEmitter/RCTEventEmitter.js +++ b/packages/react-native/Libraries/EventEmitter/RCTEventEmitter.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -12,8 +12,22 @@ import registerCallableModule from '../Core/registerCallableModule'; +type EventEmitterModule = { + receiveEvent: ( + rootNodeID: number, + topLevelType: string, + nativeEventParam: unknown, + ) => void, + receiveTouches: ( + eventTopLevelType: string, + touches: Array, + changedIndices: Array, + ) => void, + ... +}; + const RCTEventEmitter = { - register(eventEmitter: any) { + register(eventEmitter: EventEmitterModule) { registerCallableModule('RCTEventEmitter', eventEmitter); }, }; diff --git a/packages/react-native/Libraries/Interaction/PanResponder.js b/packages/react-native/Libraries/Interaction/PanResponder.js index 3c31c1a895c9..fbf0a5d5f0b2 100644 --- a/packages/react-native/Libraries/Interaction/PanResponder.js +++ b/packages/react-native/Libraries/Interaction/PanResponder.js @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/Lists/FlatList.js b/packages/react-native/Libraries/Lists/FlatList.js index ff4563be2406..6976a324b8dc 100644 --- a/packages/react-native/Libraries/Lists/FlatList.js +++ b/packages/react-native/Libraries/Lists/FlatList.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -78,10 +78,10 @@ type OptionalFlatListProps = { * any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the * `data` prop, stick it here and treat it immutably. */ - extraData?: any, + extraData?: unknown, /** * `getItemLayout` is an optional optimizations that let us skip measurement of dynamic content if - * you know the height of items a priori. `getItemLayout` is the most efficient, and is easy to + * you know the height of items a priori. * use if you have fixed height items, for example: * * getItemLayout={(data, index) => ( @@ -305,6 +305,7 @@ export type FlatListProps = Readonly<{ * * Also inherits [ScrollView Props](docs/scrollview.html#props), unless it is nested in another FlatList of same orientation. */ +// flowlint-next-line unclear-type:off class FlatList extends React.PureComponent> { /** * Scrolls to the end of the content. May be janky without `getItemLayout` prop. @@ -404,6 +405,7 @@ class FlatList extends React.PureComponent> { } } + // flowlint-next-line unclear-type:off getScrollableNode(): any { if (this._listRef) { return this._listRef.getScrollableNode(); @@ -499,7 +501,7 @@ class FlatList extends React.PureComponent> { 'FlatList does not support custom data formats.', ); if (numColumns > 1) { - invariant(!horizontal, 'numColumns does not support horizontal.'); + invariant(horizontal !== true, 'numColumns does not support horizontal.'); } else { invariant( !columnWrapperStyle, @@ -611,11 +613,13 @@ class FlatList extends React.PureComponent> { } _renderer = ( - ListItemComponent: ?(React.ComponentType | React.MixedElement), + ListItemComponent: ?( + React.ComponentType> | React.MixedElement + ), renderItem: ?ListRenderItem, columnWrapperStyle: ?ViewStyleProp, numColumns: ?number, - extraData: ?any, + extraData: ?unknown, // $FlowFixMe[missing-local-annot] ) => { const cols = numColumnsOrDefault(numColumns); diff --git a/packages/react-native/Libraries/Lists/SectionList.js b/packages/react-native/Libraries/Lists/SectionList.js index 9aa96b248aaa..bfc00d9be648 100644 --- a/packages/react-native/Libraries/Lists/SectionList.js +++ b/packages/react-native/Libraries/Lists/SectionList.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -26,6 +26,7 @@ import * as React from 'react'; const VirtualizedSectionList = VirtualizedLists.VirtualizedSectionList; type DefaultSectionT = { + // flowlint-next-line unclear-type:off [key: string]: any, }; @@ -74,7 +75,7 @@ type OptionalSectionListProps = { * any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the * `data` prop, stick it here and treat it immutably. */ - extraData?: any, + extraData?: unknown, /** * How many items to render in the initial batch. This should be enough to fill the screen but not * much more. Note these items will never be unmounted as part of the windowed rendering in order @@ -172,6 +173,7 @@ export type SectionListProps = { * @see https://reactnative.dev/docs/sectionlist */ export default class SectionList< + // flowlint-next-line unclear-type:off ItemT = any, SectionT = DefaultSectionT, > extends React.PureComponent> { @@ -226,6 +228,7 @@ export default class SectionList< /** * Provides a handle to the underlying scroll node. */ + // flowlint-next-line unclear-type:off getScrollableNode(): any { const listRef = this._wrapperListRef && this._wrapperListRef.getListRef(); if (listRef) { @@ -233,6 +236,7 @@ export default class SectionList< } } + // flowlint-next-line unclear-type:off setNativeProps(props: Object) { const listRef = this._wrapperListRef && this._wrapperListRef.getListRef(); if (listRef) { diff --git a/packages/react-native/Libraries/Lists/SectionListModern.js b/packages/react-native/Libraries/Lists/SectionListModern.js index 2661a31bc326..9ec7d56002c2 100644 --- a/packages/react-native/Libraries/Lists/SectionListModern.js +++ b/packages/react-native/Libraries/Lists/SectionListModern.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -26,6 +26,7 @@ import {useImperativeHandle, useRef} from 'react'; const VirtualizedSectionList = VirtualizedLists.VirtualizedSectionList; type DefaultSectionT = { + // flowlint-next-line unclear-type:off [key: string]: any, }; @@ -60,6 +61,7 @@ type OptionalProps = { separators: { highlight: () => void, unhighlight: () => void, + // flowlint-next-line unclear-type:off updateProps: (select: 'leading' | 'trailing', newProps: Object) => void, ... }, @@ -70,6 +72,7 @@ type OptionalProps = { * any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the * `data` prop, stick it here and treat it immutably. */ + // flowlint-next-line unclear-type:off extraData?: any, /** * How many items to render in the initial batch. This should be enough to fill the screen but not @@ -110,6 +113,9 @@ export type Props = Readonly<{ ...OptionalProps, }>; +// flowlint-next-line unclear-type:off +type SectionListComponentProps = Props; + /** * A performant interface for rendering sectioned lists, supporting the most handy features: * @@ -166,14 +172,16 @@ export type Props = Readonly<{ * */ const SectionList: component( + // flowlint-next-line unclear-type:off ref?: React.RefSetter, - ...Props + ...SectionListComponentProps ) = ({ ref, ...props }: { + // flowlint-next-line unclear-type:off ref?: React.RefSetter, - ...Props, + ...SectionListComponentProps, }) => { const propsWithDefaults = { stickySectionHeadersEnabled: Platform.OS === 'ios', @@ -224,11 +232,12 @@ const SectionList: component( wrapperRef.current?.getListRef()?.getScrollResponder(); }, + // flowlint-next-line unclear-type:off getScrollableNode(): any { wrapperRef.current?.getListRef()?.getScrollableNode(); }, - setNativeProps(nativeProps: Object) { + setNativeProps(nativeProps: {[string]: unknown}) { wrapperRef.current?.getListRef()?.setNativeProps(nativeProps); }, }), diff --git a/packages/react-native/Libraries/Lists/__flowtests__/SectionList-flowtest.js b/packages/react-native/Libraries/Lists/__flowtests__/SectionList-flowtest.js index 9f5a7efd2000..769e0da32376 100644 --- a/packages/react-native/Libraries/Lists/__flowtests__/SectionList-flowtest.js +++ b/packages/react-native/Libraries/Lists/__flowtests__/SectionList-flowtest.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -22,7 +22,7 @@ function renderMyListItem(info: { const renderMyHeader = ({ section, }: { - section: {fooNumber: number, ...} & Object, + section: {fooNumber: number, ...}, ... }) => ; diff --git a/packages/react-native/Libraries/Network/FormData.js b/packages/react-native/Libraries/Network/FormData.js index 3e7b02e669dc..551a1eca57f9 100644 --- a/packages/react-native/Libraries/Network/FormData.js +++ b/packages/react-native/Libraries/Network/FormData.js @@ -14,7 +14,7 @@ type FormDataValue = string | {name?: string, type?: string, uri: string}; type FormDataNameValuePair = [string, FormDataValue]; type Headers = {[name: string]: string, ...}; -type FormDataPart = +export type FormDataPart = | { string: string, headers: Headers, diff --git a/packages/react-native/Libraries/Network/RCTNetworking.android.js b/packages/react-native/Libraries/Network/RCTNetworking.android.js index c79b584a4d3c..846467f19ab4 100644 --- a/packages/react-native/Libraries/Network/RCTNetworking.android.js +++ b/packages/react-native/Libraries/Network/RCTNetworking.android.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -21,10 +21,11 @@ import convertRequestBody from './convertRequestBody'; import NativeNetworkingAndroid from './NativeNetworkingAndroid'; type Header = [string, string]; +type HeadersMap = {[string]: string}; // Convert FormData headers to arrays, which are easier to consume in // native on Android. -function convertHeadersMapToArray(headers: Object): Array
{ +function convertHeadersMapToArray(headers: HeadersMap): Array
{ const headerArray: Array
= []; for (const name in headers) { headerArray.push([name, headers[name]]); @@ -37,7 +38,7 @@ function generateRequestId(): number { return _requestId++; } -const emitter = new NativeEventEmitter<$FlowFixMe>( +const emitter = new NativeEventEmitter( // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior // If you want to use the native module on other platforms, please remove this condition and test its behavior Platform.OS !== 'ios' ? null : NativeNetworkingAndroid, @@ -53,7 +54,6 @@ const RCTNetworking = { listener: (...RCTNetworkingEventDefinitions[K]) => unknown, context?: unknown, ): EventSubscription { - // $FlowFixMe[incompatible-type] return emitter.addListener(eventType, listener, context); }, @@ -61,8 +61,8 @@ const RCTNetworking = { method: string, trackingName: string | void, url: string, - headers: Object, - data: RequestBody, + headers: HeadersMap, + data: ?RequestBody, responseType: NativeResponseType, incrementalUpdates: boolean, timeout: number, @@ -70,12 +70,17 @@ const RCTNetworking = { withCredentials: boolean, ) { const body = convertRequestBody(data); - if (body && body.formData) { - body.formData = body.formData.map(part => ({ - ...part, - headers: convertHeadersMapToArray(part.headers), - })); - } + const formData = body.formData; + const nativeRequestBody = + formData != null + ? { + ...body, + formData: formData.map(part => ({ + ...part, + headers: convertHeadersMapToArray(part.headers), + })), + } + : body; const requestId = generateRequestId(); const devToolsRequestId = global.__NETWORK_REPORTER__?.createDevToolsRequestId(); @@ -84,7 +89,7 @@ const RCTNetworking = { url, requestId, convertHeadersMapToArray(headers), - {...body, trackingName, devToolsRequestId}, + {...nativeRequestBody, trackingName, devToolsRequestId}, responseType, incrementalUpdates, timeout, diff --git a/packages/react-native/Libraries/Network/RCTNetworking.ios.js b/packages/react-native/Libraries/Network/RCTNetworking.ios.js index a97c96dec1f9..79bb13c8e2c2 100644 --- a/packages/react-native/Libraries/Network/RCTNetworking.ios.js +++ b/packages/react-native/Libraries/Network/RCTNetworking.ios.js @@ -32,7 +32,7 @@ const RCTNetworking = { trackingName: string | void, url: string, headers: {...}, - data: RequestBody, + data: ?RequestBody, responseType: NativeResponseType, incrementalUpdates: boolean, timeout: number, diff --git a/packages/react-native/Libraries/Network/RCTNetworking.js.flow b/packages/react-native/Libraries/Network/RCTNetworking.js.flow index c1802972b4ea..d3dccfbe5006 100644 --- a/packages/react-native/Libraries/Network/RCTNetworking.js.flow +++ b/packages/react-native/Libraries/Network/RCTNetworking.js.flow @@ -27,8 +27,8 @@ declare const RCTNetworking: interface { method: string, trackingName: string | void, url: string, - headers: {...}, - data: RequestBody, + headers: {[string]: string}, + data: ?RequestBody, responseType: NativeResponseType, incrementalUpdates: boolean, timeout: number, diff --git a/packages/react-native/Libraries/Network/XMLHttpRequest.js b/packages/react-native/Libraries/Network/XMLHttpRequest.js index 7edb4c2a24c5..e60bf98d96d1 100644 --- a/packages/react-native/Libraries/Network/XMLHttpRequest.js +++ b/packages/react-native/Libraries/Network/XMLHttpRequest.js @@ -4,16 +4,19 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + 'use strict'; import type { EventCallback, EventListener, } from '../../src/private/webapis/dom/events/EventTarget'; +import type {RequestBody} from './convertRequestBody'; import Event from '../../src/private/webapis/dom/events/Event'; import { @@ -30,20 +33,25 @@ const RCTNetworking = require('./RCTNetworking').default; const base64 = require('base64-js'); const invariant = require('invariant'); -const DEBUG_NETWORK_SEND_DELAY: false = false; // Set to a number of milliseconds when debugging +const DEBUG_NETWORK_SEND_DELAY: number = 0; // Set to a number of milliseconds when debugging export type NativeResponseType = 'base64' | 'blob' | 'text'; export type ResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text'; -export type Response = ?Object | string; +export type Response = unknown; type XHRInterceptor = interface { - requestSent(id: number, url: string, method: string, headers: Object): void, + requestSent( + id: number, + url: string, + method: string, + headers: {[string]: string}, + ): void, responseReceived( id: number, url: string, status: number, - headers: Object, + headers: {[string]: string}, ): void, dataReceived(id: number, data: string): void, loadingFinished(id: number, encodedDataLength: number): void, @@ -145,7 +153,7 @@ class XMLHttpRequest extends EventTarget { DONE: number = DONE; readyState: number = UNSENT; - responseHeaders: ?Object; + responseHeaders: ?{[string]: string}; status: number = 0; timeout: number = 0; responseURL: ?string; @@ -159,8 +167,8 @@ class XMLHttpRequest extends EventTarget { _aborted: boolean = false; _cachedResponse: Response; _hasError: boolean = false; - _headers: Object; - _lowerCaseResponseHeaders: Object; + _headers: {[string]: string}; + _lowerCaseResponseHeaders: {[string]: string}; _method: ?string = null; _perfKey: ?string = null; _responseType: ResponseType; @@ -305,8 +313,8 @@ class XMLHttpRequest extends EventTarget { XMLHttpRequest._interceptor && XMLHttpRequest._interceptor.requestSent( requestId, - this._url || '', - this._method || 'GET', + this._url ?? '', + this._method != null && this._method !== '' ? this._method : 'GET', this._headers, ); } @@ -332,7 +340,7 @@ class XMLHttpRequest extends EventTarget { __didReceiveResponse( requestId: number, status: number, - responseHeaders: ?Object, + responseHeaders: ?{[string]: string}, responseURL: ?string, ): void { if (requestId === this._requestId) { @@ -343,7 +351,7 @@ class XMLHttpRequest extends EventTarget { this.status = status; this.setResponseHeaders(responseHeaders); this.setReadyState(this.HEADERS_RECEIVED); - if (responseURL || responseURL === '') { + if (responseURL != null) { this.responseURL = responseURL; } else { delete this.responseURL; @@ -352,7 +360,9 @@ class XMLHttpRequest extends EventTarget { XMLHttpRequest._interceptor && XMLHttpRequest._interceptor.responseReceived( requestId, - responseURL || this._url || '', + responseURL != null && responseURL !== '' + ? responseURL + : (this._url ?? ''), status, responseHeaders || {}, ); @@ -509,7 +519,7 @@ class XMLHttpRequest extends EventTarget { return value !== undefined ? value : null; } - setRequestHeader(header: string, value: any): void { + setRequestHeader(header: string, value: string): void { if (this.readyState !== this.OPENED) { throw new Error('Request has not been opened'); } @@ -543,7 +553,7 @@ class XMLHttpRequest extends EventTarget { if (this.readyState !== this.UNSENT) { throw new Error('Cannot open, already sending'); } - if (async !== undefined && !async) { + if (async !== undefined && async !== true) { // async is default throw new Error('Synchronous http requests are not supported'); } @@ -556,7 +566,7 @@ class XMLHttpRequest extends EventTarget { this.setReadyState(this.OPENED); } - send(data: any): void { + send(data: ?RequestBody): void { if (this.readyState !== this.OPENED) { throw new Error('Request has not been opened'); } @@ -614,12 +624,12 @@ class XMLHttpRequest extends EventTarget { performanceLogger.startTimespan(this._perfKey); } invariant( - this._method, + this._method != null && this._method !== '', 'XMLHttpRequest method needs to be defined (%s).', friendlyName, ); invariant( - this._url, + this._url != null && this._url !== '', 'XMLHttpRequest URL needs to be defined (%s).', friendlyName, ); @@ -632,13 +642,10 @@ class XMLHttpRequest extends EventTarget { nativeResponseType, incrementalEvents, this.timeout, - // $FlowFixMe[method-unbinding] added when improving typing for this parameters - this.__didCreateRequest.bind(this), + (requestId: number) => this.__didCreateRequest(requestId), this.withCredentials, ); }; - /* $FlowFixMe[constant-condition] Error discovered during Constant - * Condition roll out. See https://fburl.com/workplace/1v97vimq. */ if (DEBUG_NETWORK_SEND_DELAY) { setTimeout(doSend, DEBUG_NETWORK_SEND_DELAY); } else { @@ -648,7 +655,7 @@ class XMLHttpRequest extends EventTarget { abort(): void { this._aborted = true; - if (this._requestId) { + if (this._requestId != null) { RCTNetworking.abortRequest(this._requestId); } // only call onreadystatechange if there is something to abort, @@ -665,13 +672,12 @@ class XMLHttpRequest extends EventTarget { this._reset(); } - setResponseHeaders(responseHeaders: ?Object): void { + setResponseHeaders(responseHeaders: ?{[string]: string}): void { this.responseHeaders = responseHeaders || null; - const headers = responseHeaders || {}; + const headers: {[string]: string} = responseHeaders || {}; this._lowerCaseResponseHeaders = Object.keys(headers).reduce<{ - [string]: any, + [string]: string, }>((lcaseHeaders, headerName) => { - // $FlowFixMe[invalid-computed-prop] lcaseHeaders[headerName.toLowerCase()] = headers[headerName]; return lcaseHeaders; }, {}); diff --git a/packages/react-native/Libraries/Network/convertRequestBody.js b/packages/react-native/Libraries/Network/convertRequestBody.js index caf79174078d..91ac9d944eea 100644 --- a/packages/react-native/Libraries/Network/convertRequestBody.js +++ b/packages/react-native/Libraries/Network/convertRequestBody.js @@ -4,13 +4,15 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ 'use strict'; import typeof BlobT from '../Blob/Blob'; +import type {BlobData} from '../Blob/BlobTypes'; +import type {FormDataPart} from './FormData'; import typeof FormDataT from './FormData'; const Blob: BlobT = require('../Blob/Blob').default; @@ -25,7 +27,16 @@ export type RequestBody = | ArrayBuffer | $ArrayBufferView; -function convertRequestBody(body: RequestBody): Object { +type RequestBodyResult = Readonly<{ + string?: string, + blob?: BlobData, + formData?: Array, + base64?: string, + uri?: string, + ... +}>; + +function convertRequestBody(body: ?RequestBody): RequestBodyResult { if (typeof body === 'string') { return {string: body}; } @@ -35,12 +46,15 @@ function convertRequestBody(body: RequestBody): Object { if (body instanceof FormData) { return {formData: body.getParts()}; } + if (body == null) { + return {}; + } if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) { /* $FlowFixMe[incompatible-type] : no way to assert that 'body' is indeed * an ArrayBufferView */ return {base64: binaryToBase64(body)}; } - return body; + return {...body}; } export default convertRequestBody; diff --git a/packages/react-native/Libraries/ReactNative/AppRegistry.js b/packages/react-native/Libraries/ReactNative/AppRegistry.js index 036749c3514a..20e2168f0d62 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistry.js +++ b/packages/react-native/Libraries/ReactNative/AppRegistry.js @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/ReactNative/AppRegistry.js.flow b/packages/react-native/Libraries/ReactNative/AppRegistry.js.flow index aa5c650107ac..792f2c87e562 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistry.js.flow +++ b/packages/react-native/Libraries/ReactNative/AppRegistry.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js b/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js index 33e0c84f3ba1..3166cbd5678d 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js +++ b/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -113,7 +113,7 @@ export function registerComponent( displayMode, }); }; - if (section) { + if (section === true) { sections[appKey] = runnables[appKey]; } return appKey; @@ -220,7 +220,7 @@ export function runApplication( */ export function setSurfaceProps( appKey: string, - appParameters: Object, + appParameters: AppParameters, displayMode?: number, ): void { if (appKey !== 'LogBox') { @@ -264,7 +264,6 @@ export function registerHeadlessTask( taskKey: string, taskProvider: TaskProvider, ): void { - // $FlowFixMe[object-this-reference] registerCancellableHeadlessTask(taskKey, taskProvider, () => () => { /* Cancel is no-op */ }); @@ -300,7 +299,7 @@ export function registerCancellableHeadlessTask( export function startHeadlessTask( taskId: number, taskKey: string, - data: any, + data: unknown, ): void { const NativeHeadlessJsTaskSupport = require('./NativeHeadlessJsTaskSupport').default; @@ -326,8 +325,7 @@ export function startHeadlessTask( NativeHeadlessJsTaskSupport && reason instanceof HeadlessJsTaskError ) { - // $FlowFixMe[unused-promise] - NativeHeadlessJsTaskSupport.notifyTaskRetry(taskId).then( + void NativeHeadlessJsTaskSupport.notifyTaskRetry(taskId).then( retryPosted => { if (!retryPosted) { NativeHeadlessJsTaskSupport.notifyTaskFinished(taskId); diff --git a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js index 0db6d3415496..4ef402b626b3 100644 --- a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js +++ b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -12,27 +12,35 @@ import type {RootTag} from '../Types/RootTagTypes'; import type {UIManagerJSInterface} from '../Types/UIManagerJSInterface'; +import type {UIManagerConstants, ViewManagerConfig} from './NativeUIManager'; +import ReactNativeElement from '../../src/private/webapis/dom/nodes/ReactNativeElement'; import {unstable_hasComponent} from '../NativeComponent/NativeComponentRegistryUnstable'; import defineLazyObjectProperty from '../Utilities/defineLazyObjectProperty'; import Platform from '../Utilities/Platform'; import {getFabricUIManager} from './FabricUIManager'; +import {getNativeTagFromPublicInstance} from './ReactFabricPublicInstance/ReactFabricPublicInstance'; +import { + getNodeFromInternalInstanceHandle, + getPublicInstanceFromInternalInstanceHandle, +} from './RendererImplementation'; import nullthrows from 'nullthrows'; function raiseSoftError(methodName: string, details?: string): void { console.error( `[ReactNative Architecture][JS] '${methodName}' is not available in the new React Native architecture.` + - (details ? ` ${details}` : ''), + (details != null && details !== '' ? ` ${details}` : ''), ); } -const getUIManagerConstants: ?() => {[viewManagerName: string]: Object} = - global.RN$LegacyInterop_UIManager_getConstants; +const getUIManagerConstants: ?() => { + [viewManagerName: string]: ViewManagerConfig, +} = global.RN$LegacyInterop_UIManager_getConstants; const getUIManagerConstantsCached = (function () { let wasCalledOnce = false; - let result: {[viewManagerName: string]: Object} = {}; - return (): {[viewManagerName: string]: Object} => { + let result: {[viewManagerName: string]: ViewManagerConfig} = {}; + return (): {[viewManagerName: string]: ViewManagerConfig} => { if (!wasCalledOnce) { result = nullthrows(getUIManagerConstants)(); wasCalledOnce = true; @@ -41,16 +49,18 @@ const getUIManagerConstantsCached = (function () { }; })(); -const getConstantsForViewManager: ?(viewManagerName: string) => ?Object = +const getConstantsForViewManager: ?( + viewManagerName: string, +) => ?ViewManagerConfig = global.RN$LegacyInterop_UIManager_getConstantsForViewManager; -const getDefaultEventTypes: ?() => Object = +const getDefaultEventTypes: ?() => ViewManagerConfig = global.RN$LegacyInterop_UIManager_getDefaultEventTypes; const getDefaultEventTypesCached = (function () { let wasCalledOnce = false; let result = null; - return (): Object => { + return (): ViewManagerConfig => { if (!wasCalledOnce) { result = nullthrows(getDefaultEventTypes)(); wasCalledOnce = true; @@ -63,7 +73,13 @@ const getDefaultEventTypesCached = (function () { * UIManager.js overrides these APIs. * Pull them out from the BridgelessUIManager implementation. So, we can ignore them. */ -const UIManagerJSOverridenAPIs = { +const UIManagerJSOverridenAPIs: { + measure: UIManagerJSInterface['measure'], + measureInWindow: UIManagerJSInterface['measureInWindow'], + measureLayout: UIManagerJSInterface['measureLayout'], + measureLayoutRelativeToParent: UIManagerJSInterface['measureLayoutRelativeToParent'], + dispatchViewManagerCommand: UIManagerJSInterface['dispatchViewManagerCommand'], +} = { measure: ( reactTag: number, callback: ( @@ -86,7 +102,7 @@ const UIManagerJSOverridenAPIs = { measureLayout: ( reactTag: number, ancestorReactTag: number, - errorCallback: (error: Object) => void, + errorCallback, callback: ( left: number, top: number, @@ -98,7 +114,7 @@ const UIManagerJSOverridenAPIs = { }, measureLayoutRelativeToParent: ( reactTag: number, - errorCallback: (error: Object) => void, + errorCallback, callback: ( left: number, top: number, @@ -111,7 +127,7 @@ const UIManagerJSOverridenAPIs = { dispatchViewManagerCommand: ( reactTag: number, commandID: number, - commandArgs: ?Array, + commandArgs, ): void => { raiseSoftError('dispatchViewManagerCommand'); }, @@ -122,16 +138,23 @@ const UIManagerJSOverridenAPIs = { * In OSS, the New Architecture will just use the Fabric renderer, which uses * different APIs. */ -const UIManagerJSUnusedInNewArchAPIs = { +const UIManagerJSUnusedInNewArchAPIs: { + createView: UIManagerJSInterface['createView'], + updateView: UIManagerJSInterface['updateView'], + setChildren: UIManagerJSInterface['setChildren'], + manageChildren: UIManagerJSInterface['manageChildren'], + setJSResponder: UIManagerJSInterface['setJSResponder'], + clearJSResponder: UIManagerJSInterface['clearJSResponder'], +} = { createView: ( reactTag: number, viewName: string, rootTag: RootTag, - props: Object, + props, ): void => { raiseSoftError('createView'); }, - updateView: (reactTag: number, viewName: string, props: Object): void => { + updateView: (reactTag: number, viewName: string, props): void => { raiseSoftError('updateView'); }, setChildren: (containerTag: number, reactTags: Array): void => { @@ -165,7 +188,9 @@ const UIManagerJSDeprecatedPlatformAPIs = Platform.select({ const UIManagerJSPlatformAPIs = Platform.select({ android: { - getConstantsForViewManager: (viewManagerName: string): ?Object => { + getConstantsForViewManager: ( + viewManagerName: string, + ): ?ViewManagerConfig => { if (getConstantsForViewManager) { return getConstantsForViewManager(viewManagerName); } @@ -217,7 +242,7 @@ const UIManagerJSPlatformAPIs = Platform.select({ const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (!shadowNode) { + if (shadowNode == null) { console.error( `sendAccessibilityEvent() dropping event: Cannot find view with tag #${reactTag}`, ); @@ -233,7 +258,7 @@ const UIManagerJSPlatformAPIs = Platform.select({ * * Leave this unimplemented until we implement lazy loading of legacy modules and view managers in the new architecture. */ - lazilyLoadView: (name: string): Object => { + lazilyLoadView: (name: string): ViewManagerConfig => { raiseSoftError('lazilyLoadView'); return {}; }, @@ -241,7 +266,7 @@ const UIManagerJSPlatformAPIs = Platform.select({ const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (!shadowNode) { + if (shadowNode == null) { console.error(`focus() noop: Cannot find view with tag #${reactTag}`); return; } @@ -251,7 +276,7 @@ const UIManagerJSPlatformAPIs = Platform.select({ const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (!shadowNode) { + if (shadowNode == null) { console.error(`blur() noop: Cannot find view with tag #${reactTag}`); return; } @@ -260,12 +285,12 @@ const UIManagerJSPlatformAPIs = Platform.select({ }, }); -const UIManagerJS: UIManagerJSInterface & {[string]: any} = { +const UIManagerJS: UIManagerJSInterface & {[string]: ViewManagerConfig} = { ...UIManagerJSOverridenAPIs, ...UIManagerJSDeprecatedPlatformAPIs, ...UIManagerJSPlatformAPIs, ...UIManagerJSUnusedInNewArchAPIs, - getViewManagerConfig: (viewManagerName: string): unknown => { + getViewManagerConfig: (viewManagerName: string): ViewManagerConfig => { if (getUIManagerConstants) { const constants = getUIManagerConstantsCached(); if ( @@ -287,7 +312,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { hasViewManagerConfig: (viewManagerName: string): boolean => { return unstable_hasComponent(viewManagerName); }, - getConstants: (): Object => { + getConstants: (): UIManagerConstants => { if (getUIManagerConstants) { return getUIManagerConstantsCached(); } else { @@ -309,7 +334,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (!shadowNode) { + if (shadowNode == null) { console.error( `findSubviewIn() noop: Cannot find view with reactTag ${reactTag}`, ); @@ -326,16 +351,21 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { return; } - let instanceHandle: Object = internalInstanceHandle; - let node = instanceHandle.stateNode.node; + const node = getNodeFromInternalInstanceHandle(internalInstanceHandle); + if (node == null) { + console.error('findSubviewIn(): Cannot find node at point'); + return; + } - if (!node) { + const publicInstance = getPublicInstanceFromInternalInstanceHandle( + internalInstanceHandle, + ); + if (!(publicInstance instanceof ReactNativeElement)) { console.error('findSubviewIn(): Cannot find node at point'); return; } - let nativeViewTag: number = - instanceHandle.stateNode.canonical.nativeTag; + const nativeViewTag = getNativeTagFromPublicInstance(publicInstance); FabricUIManager.measure( node, @@ -353,7 +383,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { ): void => { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (!shadowNode) { + if (shadowNode == null) { console.error( `viewIsDescendantOf() noop: Cannot find view with reactTag ${reactTag}`, ); @@ -362,7 +392,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { const ancestorShadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(ancestorReactTag); - if (!ancestorShadowNode) { + if (ancestorShadowNode == null) { console.error( `viewIsDescendantOf() noop: Cannot find view with ancestorReactTag ${ancestorReactTag}`, ); @@ -382,11 +412,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { callback([isAncestor]); }, - configureNextLayoutAnimation: ( - config: Object, - callback: () => void, - errorCallback: (error: Object) => void, - ): void => { + configureNextLayoutAnimation: (config, callback, errorCallback): void => { const FabricUIManager = nullthrows(getFabricUIManager()); FabricUIManager.configureNextLayoutAnimation( config, diff --git a/packages/react-native/Libraries/ReactNative/PaperUIManager.js b/packages/react-native/Libraries/ReactNative/PaperUIManager.js index fadf460022fd..151b06fe457c 100644 --- a/packages/react-native/Libraries/ReactNative/PaperUIManager.js +++ b/packages/react-native/Libraries/ReactNative/PaperUIManager.js @@ -4,12 +4,13 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ import type {RootTag} from '../Types/RootTagTypes'; import type {UIManagerJSInterface} from '../Types/UIManagerJSInterface'; +import type {UIManagerConstants, ViewManagerConfig} from './NativeUIManager'; import NativeUIManager from './NativeUIManager'; import nullthrows from 'nullthrows'; @@ -20,13 +21,13 @@ const defineLazyObjectProperty = const Platform = require('../Utilities/Platform').default; const UIManagerProperties = require('./UIManagerProperties').default; -const viewManagerConfigs: {[string]: any | null} = {}; +const viewManagerConfigs: {[string]: ViewManagerConfig | null} = {}; const triedLoadingConfig = new Set(); let NativeUIManagerConstants = {}; let isNativeUIManagerConstantsSet = false; -function getConstants(): Object { +function getConstants(): UIManagerConstants { if (!isNativeUIManagerConstantsSet) { NativeUIManagerConstants = NativeUIManager.getConstants(); isNativeUIManagerConstantsSet = true; @@ -34,7 +35,7 @@ function getConstants(): Object { return NativeUIManagerConstants; } -function getViewManagerConfig(viewManagerName: string): any { +function getViewManagerConfig(viewManagerName: string): ViewManagerConfig { if ( viewManagerConfigs[viewManagerName] === undefined && NativeUIManager.getConstantsForViewManager @@ -86,7 +87,7 @@ const UIManagerJS: UIManagerJSInterface = { reactTag: number, viewName: string, rootTag: RootTag, - props: Object, + props, ): void { if (Platform.OS === 'ios' && viewManagerConfigs[viewName] === undefined) { // This is necessary to force the initialization of native viewManager @@ -96,10 +97,10 @@ const UIManagerJS: UIManagerJSInterface = { NativeUIManager.createView(reactTag, viewName, rootTag, props); }, - getConstants(): Object { + getConstants(): UIManagerConstants { return getConstants(); }, - getViewManagerConfig(viewManagerName: string): any { + getViewManagerConfig(viewManagerName: string): ViewManagerConfig { return getViewManagerConfig(viewManagerName); }, hasViewManagerConfig(viewManagerName: string): boolean { diff --git a/packages/react-native/Libraries/ReactNative/UIManager.js b/packages/react-native/Libraries/ReactNative/UIManager.js index a97c6a7b3ea7..a020393458ab 100644 --- a/packages/react-native/Libraries/ReactNative/UIManager.js +++ b/packages/react-native/Libraries/ReactNative/UIManager.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -60,7 +60,7 @@ const UIManager: UIManagerJSInterface = { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (shadowNode) { + if (shadowNode != null) { FabricUIManager.measure(shadowNode, callback); } else { console.warn(`measure cannot find view with tag #${reactTag}`); @@ -103,7 +103,7 @@ const UIManager: UIManagerJSInterface = { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (shadowNode) { + if (shadowNode != null) { FabricUIManager.measureInWindow(shadowNode, callback); } else { console.warn(`measure cannot find view with tag #${reactTag}`); @@ -129,7 +129,7 @@ const UIManager: UIManagerJSInterface = { measureLayout( reactTag: number, ancestorReactTag: number, - errorCallback: (error: Object) => void, + errorCallback, callback: ( left: number, top: number, @@ -144,7 +144,7 @@ const UIManager: UIManagerJSInterface = { const ancestorShadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(ancestorReactTag); - if (!shadowNode || !ancestorShadowNode) { + if (shadowNode == null || ancestorShadowNode == null) { return; } @@ -167,7 +167,7 @@ const UIManager: UIManagerJSInterface = { measureLayoutRelativeToParent( reactTag: number, - errorCallback: (error: Object) => void, + errorCallback, callback: ( left: number, top: number, @@ -182,7 +182,7 @@ const UIManager: UIManagerJSInterface = { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (shadowNode) { + if (shadowNode != null) { FabricUIManager.measure( shadowNode, (left, top, width, height, pageX, pageY) => { @@ -210,7 +210,7 @@ const UIManager: UIManagerJSInterface = { dispatchViewManagerCommand( reactTag: number, commandName: number | string, - commandArgs: any[], + commandArgs: Array, ) { // Sometimes, libraries directly pass in the output of `findNodeHandle` to // this function without checking if it's null. This guards against that @@ -224,12 +224,16 @@ const UIManager: UIManagerJSInterface = { const FabricUIManager = nullthrows(getFabricUIManager()); const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); - if (shadowNode) { + if (shadowNode != null) { // Transform the accidental CommandID into a CommandName which is the stringified number. // The interop layer knows how to convert this number into the right method name. // Stringify a string is a no-op, so it's safe. - commandName = `${commandName}`; - FabricUIManager.dispatchCommand(shadowNode, commandName, commandArgs); + const resolvedCommandName = `${commandName}`; + FabricUIManager.dispatchCommand( + shadowNode, + resolvedCommandName, + commandArgs, + ); } } else { UIManagerImpl.dispatchViewManagerCommand( diff --git a/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js b/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js index 26846a19c551..c684465410c1 100644 --- a/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js +++ b/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js @@ -4,12 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ 'use strict'; +import type {ViewManagerConfig} from './NativeUIManager'; + import processBoxShadow from '../StyleSheet/processBoxShadow'; const ReactNativeStyleAttributes = @@ -33,7 +35,9 @@ const sizesDiffer = require('../Utilities/differ/sizesDiffer').default; const UIManager = require('./UIManager').default; const nullthrows = require('nullthrows'); -function getNativeComponentAttributes(uiViewClassName: string): any { +function getNativeComponentAttributes( + uiViewClassName: string, +): ViewManagerConfig { const viewConfig = UIManager.getViewManagerConfig(uiViewClassName); if (viewConfig == null) { @@ -109,17 +113,14 @@ function getNativeComponentAttributes(uiViewClassName: string): any { return viewConfig; } -function attachDefaultEventTypes(viewConfig: any) { +function attachDefaultEventTypes(viewConfig: ViewManagerConfig) { // This is supported on UIManager platforms (ex: Android), // as lazy view managers are not implemented for all platforms. // See [UIManager] for details on constants and implementations. const constants = UIManager.getConstants(); if (constants.ViewManagerNames || constants.LazyViewManagersEnabled) { // Lazy view managers enabled. - viewConfig = merge( - viewConfig, - nullthrows(UIManager.getDefaultEventTypes)(), - ); + merge(viewConfig, nullthrows(UIManager.getDefaultEventTypes)()); } else { viewConfig.bubblingEventTypes = merge( viewConfig.bubblingEventTypes, @@ -133,7 +134,10 @@ function attachDefaultEventTypes(viewConfig: any) { } // TODO: Figure out how to avoid all this runtime initialization cost. -function merge(destination: ?Object, source: ?Object): ?Object { +function merge( + destination: ?ViewManagerConfig, + source: ?ViewManagerConfig, +): ?ViewManagerConfig { if (!source) { return destination; } @@ -163,7 +167,12 @@ function merge(destination: ?Object, source: ?Object): ?Object { function getDifferForType( typeName: string, -): ?(prevProp: any, nextProp: any) => boolean { +): ?( + | typeof insetsDiffer + | typeof matricesDiffer + | typeof pointsDiffer + | typeof sizesDiffer +) { switch (typeName) { // iOS Types case 'CATransform3D': @@ -183,7 +192,19 @@ function getDifferForType( return null; } -function getProcessorForType(typeName: string): ?(nextProp: any) => any { +function getProcessorForType( + typeName: string, +): ?( + | typeof processBackgroundImage + | typeof processBackgroundPosition + | typeof processBackgroundRepeat + | typeof processBackgroundSize + | typeof processBoxShadow + | typeof processColor + | typeof processColorArray + | typeof processFilter + | typeof resolveAssetSource +) { switch (typeName) { // iOS Types case 'CGColor': diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheet.js b/packages/react-native/Libraries/StyleSheet/StyleSheet.js index 529b9f3b6568..a6ec58a3fc9d 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheet.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheet.js @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow b/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow index 101d782aa278..28c096e51e00 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow +++ b/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow index 2aa4ee1d3ffb..9520c8d24788 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -86,9 +86,9 @@ declare export const flatten: typeof flattenStyle; * internally to process color and transform values. You should not use this * unless you really know what you are doing and have exhausted other options. */ -declare export const setStyleAttributePreprocessor: ( +declare export const setStyleAttributePreprocessor: ( property: string, - process: (nextProp: any) => any, + process: (nextProp: T) => unknown, ) => void; /** diff --git a/packages/react-native/Libraries/StyleSheet/processFilter.js b/packages/react-native/Libraries/StyleSheet/processFilter.js index 50e3e04ef1b7..d7ed54f17ff9 100644 --- a/packages/react-native/Libraries/StyleSheet/processFilter.js +++ b/packages/react-native/Libraries/StyleSheet/processFilter.js @@ -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. * - * @flow + * @flow strict-local * @format strict-local */ @@ -51,13 +51,13 @@ export default function processFilter( } if (typeof filter === 'string') { - filter = filter.replace(NEWLINE_REGEX, ' '); + const normalizedFilter = filter.replace(NEWLINE_REGEX, ' '); // matches on functions with args and nested functions like "drop-shadow(10 10 10 rgba(0, 0, 0, 1))" FILTER_FUNCTION_REGEX.lastIndex = 0; let matches; - while ((matches = FILTER_FUNCTION_REGEX.exec(filter))) { + while ((matches = FILTER_FUNCTION_REGEX.exec(normalizedFilter))) { let filterName = matches[1].toLowerCase(); if (filterName === 'drop-shadow') { const dropShadow = parseDropShadow(matches[2]); @@ -159,7 +159,10 @@ function _getFilterAmount(filterName: string, filterArgs: unknown): ?number { // blur takes any positive CSS length that is not a percent. In RN // we currently only have DIPs, so we are not parsing units here. case 'blur': - if ((unit && unit !== 'px') || filterArgAsNumber < 0) { + if ( + (unit != null && unit !== '' && unit !== 'px') || + filterArgAsNumber < 0 + ) { return undefined; } return filterArgAsNumber; @@ -173,7 +176,10 @@ function _getFilterAmount(filterName: string, filterArgs: unknown): ?number { case 'opacity': case 'saturate': case 'sepia': - if ((unit && unit !== '%' && unit !== 'px') || filterArgAsNumber < 0) { + if ( + (unit != null && unit !== '' && unit !== '%' && unit !== 'px') || + filterArgAsNumber < 0 + ) { return undefined; } if (unit === '%') { diff --git a/packages/react-native/Libraries/StyleSheet/processTransformOrigin.js b/packages/react-native/Libraries/StyleSheet/processTransformOrigin.js index 5c132d92ae43..b90d3ced96e0 100644 --- a/packages/react-native/Libraries/StyleSheet/processTransformOrigin.js +++ b/packages/react-native/Libraries/StyleSheet/processTransformOrigin.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -20,10 +20,11 @@ const INDEX_Z = 2; /* eslint-disable no-labels */ export default function processTransformOrigin( - transformOrigin: Array | string, + transformOriginInput: Array | string, ): Array { - if (typeof transformOrigin === 'string') { - const transformOriginString = transformOrigin; + let transformOrigin: Array; + if (typeof transformOriginInput === 'string') { + const transformOriginString = transformOriginInput; TRANSFORM_ORIGIN_REGEX.lastIndex = 0; const transformOriginArray: Array = ['50%', '50%', 0]; @@ -111,6 +112,8 @@ export default function processTransformOrigin( } transformOrigin = transformOriginArray; + } else { + transformOrigin = transformOriginInput; } if (__DEV__) { diff --git a/packages/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js b/packages/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js index b412b260a30c..975243ad9eed 100644 --- a/packages/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js +++ b/packages/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -17,15 +17,16 @@ * alpha should be number between 0 and 1 */ function setNormalizedColorAlpha(input: number, alpha: number): number { - if (alpha < 0) { - alpha = 0; - } else if (alpha > 1) { - alpha = 1; + let normalizedAlpha = alpha; + if (normalizedAlpha < 0) { + normalizedAlpha = 0; + } else if (normalizedAlpha > 1) { + normalizedAlpha = 1; } - alpha = Math.round(alpha * 255); + normalizedAlpha = Math.round(normalizedAlpha * 255); // magic bitshift guarantees we return an unsigned int - return ((input & 0xffffff00) | alpha) >>> 0; + return ((input & 0xffffff00) | normalizedAlpha) >>> 0; } export default setNormalizedColorAlpha; diff --git a/packages/react-native/Libraries/Types/UIManagerJSInterface.js b/packages/react-native/Libraries/Types/UIManagerJSInterface.js index 26d59a2c13c4..31a07cb1f807 100644 --- a/packages/react-native/Libraries/Types/UIManagerJSInterface.js +++ b/packages/react-native/Libraries/Types/UIManagerJSInterface.js @@ -4,13 +4,13 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ -import type {Spec} from '../ReactNative/NativeUIManager'; +import type {Spec, ViewManagerConfig} from '../ReactNative/NativeUIManager'; export interface UIManagerJSInterface extends Spec { - readonly getViewManagerConfig: (viewManagerName: string) => Object; + readonly getViewManagerConfig: (viewManagerName: string) => ViewManagerConfig; readonly hasViewManagerConfig: (viewManagerName: string) => boolean; } diff --git a/packages/react-native/Libraries/Utilities/BackHandler.js.flow b/packages/react-native/Libraries/Utilities/BackHandler.js.flow index 68cc9095f5b5..4c1debea88b0 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.js.flow +++ b/packages/react-native/Libraries/Utilities/BackHandler.js.flow @@ -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. * - * @flow + * @flow strict-local * @format */ diff --git a/packages/react-native/Libraries/Utilities/FeatureDetection.js b/packages/react-native/Libraries/Utilities/FeatureDetection.js index 83cdd80ac4e1..3429a76f04ab 100644 --- a/packages/react-native/Libraries/Utilities/FeatureDetection.js +++ b/packages/react-native/Libraries/Utilities/FeatureDetection.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -15,7 +15,9 @@ * Note that a polyfill can technically fake this behavior but few does it. * Therefore, this is usually good enough for our purpose. */ -export function isNativeFunction(f: Function): boolean { +export function isNativeFunction( + f: (...args: ReadonlyArray) => unknown, +): boolean { return typeof f === 'function' && f.toString().indexOf('[native code]') > -1; } @@ -23,7 +25,10 @@ export function isNativeFunction(f: Function): boolean { * @return whether or not the constructor of @param {object} o is an native * function named with @param {string} expectedName. */ -export function hasNativeConstructor(o: Object, expectedName: string): boolean { +export function hasNativeConstructor( + o: interface {}, + expectedName: string, +): boolean { const con = Object.getPrototypeOf(o).constructor; return con.name === expectedName && isNativeFunction(con); } diff --git a/packages/react-native/Libraries/Utilities/differ/insetsDiffer.js b/packages/react-native/Libraries/Utilities/differ/insetsDiffer.js index 0742df32c31e..c504e64543a1 100644 --- a/packages/react-native/Libraries/Utilities/differ/insetsDiffer.js +++ b/packages/react-native/Libraries/Utilities/differ/insetsDiffer.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -26,14 +26,14 @@ const dummyInsets = { }; function insetsDiffer(one: Inset, two: Inset): boolean { - one = one || dummyInsets; - two = two || dummyInsets; + const insetOne = one || dummyInsets; + const insetTwo = two || dummyInsets; return ( - one !== two && - (one.top !== two.top || - one.left !== two.left || - one.right !== two.right || - one.bottom !== two.bottom) + insetOne !== insetTwo && + (insetOne.top !== insetTwo.top || + insetOne.left !== insetTwo.left || + insetOne.right !== insetTwo.right || + insetOne.bottom !== insetTwo.bottom) ); } diff --git a/packages/react-native/Libraries/Utilities/differ/pointsDiffer.js b/packages/react-native/Libraries/Utilities/differ/pointsDiffer.js index 9bf891f914e2..0c02cad24a66 100644 --- a/packages/react-native/Libraries/Utilities/differ/pointsDiffer.js +++ b/packages/react-native/Libraries/Utilities/differ/pointsDiffer.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -19,9 +19,12 @@ type Point = { const dummyPoint: Point = {x: undefined, y: undefined}; function pointsDiffer(one: ?Point, two: ?Point): boolean { - one = one || dummyPoint; - two = two || dummyPoint; - return one !== two && (one.x !== two.x || one.y !== two.y); + const onePoint = one ?? dummyPoint; + const twoPoint = two ?? dummyPoint; + return ( + onePoint !== twoPoint && + (onePoint.x !== twoPoint.x || onePoint.y !== twoPoint.y) + ); } export default pointsDiffer; diff --git a/packages/react-native/Libraries/Utilities/stringifyViewConfig.js b/packages/react-native/Libraries/Utilities/stringifyViewConfig.js index 419bce0a8ba6..419de5b44902 100644 --- a/packages/react-native/Libraries/Utilities/stringifyViewConfig.js +++ b/packages/react-native/Libraries/Utilities/stringifyViewConfig.js @@ -4,19 +4,21 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ -export default function stringifyViewConfig(viewConfig: any): string { - return JSON.stringify( - viewConfig, - (key, val) => { - if (typeof val === 'function') { - return `ƒ ${val.name}`; - } - return val; - }, - 2, +export default function stringifyViewConfig(viewConfig: unknown): string { + return ( + JSON.stringify( + viewConfig, + (key, val) => { + if (typeof val === 'function') { + return `ƒ ${val.name}`; + } + return val; + }, + 2, + ) ?? '' ); } diff --git a/packages/react-native/Libraries/WebSocket/WebSocket.js b/packages/react-native/Libraries/WebSocket/WebSocket.js index 6ed5630f7438..0a48672d8696 100644 --- a/packages/react-native/Libraries/WebSocket/WebSocket.js +++ b/packages/react-native/Libraries/WebSocket/WebSocket.js @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ +// flowlint unsafe-getters-setters:off + import type {EventCallback} from '../../src/private/webapis/dom/events/EventTarget'; import type {BlobData} from '../Blob/BlobTypes'; import type {EventSubscription} from '../vendor/emitter/EventEmitter'; @@ -98,29 +100,29 @@ class WebSocket extends EventTarget { constructor( url: string, protocols: ?string | ?Array, - options: ?{headers?: {origin?: string, ...}, ...}, + options: ?{headers?: {origin?: string, ...}, origin?: string, ...}, ) { super(); this.url = url; - if (typeof protocols === 'string') { - protocols = [protocols]; - } - - const {headers = {}, ...unrecognized} = options || {}; + const protocolList: ?Array = + typeof protocols === 'string' + ? [protocols] + : Array.isArray(protocols) + ? protocols + : null; + + const {headers = {}, ...unrecognized} = (options ?? {}) as { + headers?: {origin?: string, ...}, + origin?: string, + ... + }; // Preserve deprecated backwards compatibility for the 'origin' option - // $FlowFixMe[prop-missing] if (unrecognized && typeof unrecognized.origin === 'string') { console.warn( 'Specifying `origin` as a WebSocket connection option is deprecated. Include it under `headers` instead.', ); - /* $FlowFixMe[prop-missing] (>=0.54.0 site=react_native_fb,react_native_ - * oss) This comment suppresses an error found when Flow v0.54 was - * deployed. To see the error delete this comment and run Flow. */ headers.origin = unrecognized.origin; - /* $FlowFixMe[prop-missing] (>=0.54.0 site=react_native_fb,react_native_ - * oss) This comment suppresses an error found when Flow v0.54 was - * deployed. To see the error delete this comment and run Flow. */ delete unrecognized.origin; } @@ -134,10 +136,6 @@ class WebSocket extends EventTarget { ); } - if (!Array.isArray(protocols)) { - protocols = null; - } - this._eventEmitter = new NativeEventEmitter( // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior // If you want to use the native module on other platforms, please remove this condition and test its behavior @@ -149,7 +147,7 @@ class WebSocket extends EventTarget { global.__NETWORK_REPORTER__?.createDevToolsRequestId(); NativeWebSocketModule.connect( url, - protocols, + protocolList, {headers, unstable_devToolsRequestId: devToolsRequestId}, this._socketId, ); diff --git a/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js b/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js index 57c5c8910737..38c0a45aac49 100644 --- a/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +++ b/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js @@ -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. * - * @flow + * @flow strict-local * @format */ @@ -15,7 +15,7 @@ import * as React from 'react'; function takesHostComponentInstance(instance: HostInstance | null): void {} -const MyHostComponent = 'Host' as any as HostComponent<{...}>; +declare const MyHostComponent: HostComponent<{...}>; { diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index 24f632825a84..90ae080b97ad 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<> + * @generated SignedSource<> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -336,8 +336,10 @@ declare const RCTNetworking_default: { method: string, trackingName: string | void, url: string, - headers: {}, - data: RequestBody, + headers: { + [$$Key$$: string]: string + }, + data: RequestBody | undefined, responseType: NativeResponseType, incrementalUpdates: boolean, timeout: number, @@ -371,9 +373,9 @@ declare const sequence: typeof $$AnimatedImplementation.sequence declare const sequenceImpl: ( animations: Array, ) => CompositeAnimation -declare const setStyleAttributePreprocessor: ( +declare const setStyleAttributePreprocessor: ( property: string, - process: (nextProp: any) => any, + process: (nextProp: T) => unknown, ) => void declare const Settings: typeof Settings_default declare let Settings_default: { @@ -1384,15 +1386,15 @@ declare class AnimatedTracking_default extends AnimatedNode_default { constructor( value: AnimatedValue_default, parent: AnimatedNode_default, - animationClass: any, - animationConfig: Object, + animationClass: new (...args: any[]) => Animation_default, + animationConfig: TrackingAnimationConfig, callback?: EndCallback | null | undefined, config?: AnimatedNodeConfig | null | undefined, ) update(): void } declare class AnimatedValue_default extends AnimatedWithChildren_default { - addListener(callback: (value: any) => unknown): string + addListener(callback: (value: { value: number }) => unknown): string animate( animation: Animation_default, callback: EndCallback | null | undefined, @@ -1766,7 +1768,7 @@ declare function counterEvent(eventName: EventName, value: number): void declare type create = typeof create declare type createAnimatedComponent = typeof createAnimatedComponent declare function createAnimatedComponent_default< - TInstance extends React.ComponentType, + TInstance extends React.ComponentType, >( Component: TInstance, ): AnimatedComponentType< @@ -1960,7 +1962,7 @@ declare interface DrawerLayoutAndroidMethods { onFail?: () => void, ): void openDrawer(): void - setNativeProps(nativeProps: Object): void + setNativeProps(nativeProps: {}): void } declare type DrawerLayoutAndroidProps = Readonly< ViewProps & { @@ -2913,7 +2915,7 @@ declare type LoopAnimationConfig = { iterations: number resetBeforeIteration?: boolean } -declare type LooseOmit = Pick< +declare type LooseOmit = Pick< O, Exclude > @@ -3242,7 +3244,7 @@ declare type OnAnimationDidFailCallback = () => void declare type OpaqueColorValue = NativeColorValue declare type OptionalFlatListProps = { columnWrapperStyle?: ViewStyleProp - extraData?: any + extraData?: unknown fadingEdgeLength?: | (number | undefined) | { @@ -3269,7 +3271,7 @@ declare type OptionalFlatListProps = { } declare type OptionalPlatformSelectSpec = { [key in PlatformOSType]?: T } declare type OptionalSectionListProps = { - extraData?: any + extraData?: unknown initialNumToRender?: number inverted?: boolean keyExtractor?: (item: ItemT, index: number) => string @@ -4445,7 +4447,7 @@ declare type setStyleAttributePreprocessor = typeof setStyleAttributePreprocessor declare function setSurfaceProps( appKey: string, - appParameters: Object, + appParameters: AppParameters, displayMode?: number, ): void declare type Settings = typeof Settings @@ -4507,9 +4509,9 @@ declare interface Spec extends TurboModule { readonly focus?: (reactTag: number) => void readonly getConstantsForViewManager?: ( viewManagerName: string, - ) => Object | undefined + ) => undefined | ViewManagerConfig readonly getDefaultEventTypes?: () => Array - readonly lazilyLoadView?: (name: string) => Object + readonly lazilyLoadView?: (name: string) => ViewManagerConfig readonly sendAccessibilityEvent?: ( reactTag: number, eventType: number, @@ -4517,20 +4519,20 @@ declare interface Spec extends TurboModule { readonly setLayoutAnimationEnabledExperimental?: (enabled: boolean) => void readonly clearJSResponder: () => void readonly configureNextLayoutAnimation: ( - config: Object, + config: UnsafeObject, callback: () => void, - errorCallback: (error: Object) => void, + errorCallback: (error: UnsafeObject) => void, ) => void readonly createView: ( reactTag: number, viewName: string, rootTag: RootTag, - props: Object, + props: UnsafeObject, ) => void readonly dispatchViewManagerCommand: ( reactTag: number, commandID: number, - commandArgs?: Array, + commandArgs?: Array, ) => void readonly findSubviewIn: ( reactTag: number, @@ -4543,7 +4545,7 @@ declare interface Spec extends TurboModule { height: number, ) => void, ) => void - readonly getConstants: () => Object + readonly getConstants: () => UIManagerConstants readonly manageChildren: ( containerTag: number, moveFromIndices: Array, @@ -4563,12 +4565,12 @@ declare interface Spec extends TurboModule { readonly measureLayout: ( reactTag: number, ancestorReactTag: number, - errorCallback: (error: Object) => void, + errorCallback: (error: UnsafeObject) => void, callback: NativeMeasureLayoutOnSuccessCallback, ) => void readonly measureLayoutRelativeToParent: ( reactTag: number, - errorCallback: (error: Object) => void, + errorCallback: (error: UnsafeObject) => void, callback: ( left: number, top: number, @@ -4584,7 +4586,7 @@ declare interface Spec extends TurboModule { readonly updateView: ( reactTag: number, viewName: string, - props: Object, + props: UnsafeObject, ) => void readonly viewIsDescendantOf: ( reactTag: number, @@ -4643,13 +4645,13 @@ declare type StackProps = { | undefined | { animated: boolean - value: StatusBarProps["barStyle"] + value: StatusBarStyle } hidden: | undefined | { animated: boolean - transition: StatusBarProps["showHideTransition"] + transition: StatusBarAnimation value: boolean } } @@ -4657,7 +4659,7 @@ declare type stagger = typeof stagger declare function startHeadlessTask( taskId: number, taskKey: string, - data: any, + data: unknown, ): void declare type State = { cellsAroundViewport: { @@ -5336,6 +5338,11 @@ declare function trace( fn: () => T, args?: EventArgs, ): T +declare type TrackingAnimationConfig = Readonly< + AnimationConfig & { + toValue: AnimatedNode_default + } +> declare type TransformsStyle = ____TransformStyle_Internal declare interface TurboModule extends DEPRECATED_RCTExport {} declare namespace TurboModuleRegistry { @@ -5350,8 +5357,9 @@ declare type TVViewPropsIOS = { readonly tvParallaxTiltAngle?: number } declare type UIManager = typeof UIManager +declare type UIManagerConstants = UnsafeObject declare interface UIManagerJSInterface extends Spec { - readonly getViewManagerConfig: (viewManagerName: string) => Object + readonly getViewManagerConfig: (viewManagerName: string) => ViewManagerConfig readonly hasViewManagerConfig: (viewManagerName: string) => boolean } declare type unforkEvent = typeof unforkEvent @@ -5497,6 +5505,7 @@ declare type ViewConfig = { readonly validAttributes: AttributeConfiguration } declare type ViewInstance = HostInstance +declare type ViewManagerConfig = UnsafeObject declare interface ViewProps extends Readonly< DirectEventProps & GestureResponderHandlers & @@ -5714,9 +5723,9 @@ export { AlertOptions, // 8a116d2a AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // 50cbe576 + Animated, // 51ae1ed0 AppConfig, // 35c0ca70 - AppRegistry, // 1e8c5a00 + AppRegistry, // 54cbc34d AppState, // 12012be5 AppStateEvent, // 80f034c3 AppStateStatus, // 447e5ef2 @@ -5728,8 +5737,8 @@ export { BackPressEventName, // 4620fb76 BlurEvent, // 4ba4f941 BoxShadowValue, // b679703f - Button, // bc8f6464 - ButtonInstance, // d94b4241 + Button, // f2435367 + ButtonInstance, // e4d65823 ButtonProps, // 21c5780c Clipboard, // 41addb89 CodegenTypes, // ab4986cc @@ -5748,8 +5757,8 @@ export { DimensionsPayload, // 653bc26c DisplayMetrics, // 1dc35cef DisplayMetricsAndroid, // 872e62eb - DrawerLayoutAndroid, // 7843b7b5 - DrawerLayoutAndroidInstance, // c0694352 + DrawerLayoutAndroid, // 58bc08bc + DrawerLayoutAndroidInstance, // aa243cbf DrawerLayoutAndroidProps, // 0c1d6155 DrawerSlideEvent, // c4ab8fba DropShadowValue, // e9df2606 @@ -5766,9 +5775,9 @@ export { EventSubscription, // b8d084aa ExtendedExceptionData, // 5a6ccf5a FilterFunction, // bf24c0e3 - FlatList, // e1b005c7 - FlatListInstance, // 2d1d8e45 - FlatListProps, // 94fa2dc7 + FlatList, // 171059bc + FlatListInstance, // ead0b62b + FlatListProps, // 80710cf1 FocusEvent, // 850f1517 FontVariant, // 7c7558bb GestureResponderEvent, // 14d3e77a @@ -5854,7 +5863,7 @@ export { NativeSyntheticEvent, // 534aaa92 NativeTouchEvent, // 59b676df NativeUIEvent, // 44ac26ac - Networking, // bbc5be42 + Networking, // bd182394 OpaqueColorValue, // 25f3fa5b PackagerAsset, // d1c88cf4 PanResponder, // e4df325a @@ -5909,18 +5918,18 @@ export { ScrollEvent, // d7abdd0a ScrollResponderType, // ba188eae ScrollToLocationParamsType, // d7ecdad1 - ScrollView, // 066a8597 + ScrollView, // f1d46d64 ScrollViewImperativeMethods, // 904c66fd ScrollViewInstance, // ccf4f341 - ScrollViewProps, // b62913d1 + ScrollViewProps, // 8434d563 ScrollViewPropsAndroid, // 02f3df2e ScrollViewPropsIOS, // 807cb4f6 ScrollViewScrollToOptions, // 3313411e SectionBase, // 9f13db00 - SectionList, // ee3e7972 + SectionList, // 22fb1f1f SectionListData, // 1a4de01a - SectionListInstance, // c9b991fe - SectionListProps, // 0e933318 + SectionListInstance, // 297fe811 + SectionListProps, // 47274631 SectionListRenderItem, // 715b2086 SectionListRenderItemInfo, // 4a48a922 Separators, // 6a45f7e3 @@ -5931,13 +5940,13 @@ export { ShareActionSheetIOSOptions, // eff574f5 ShareContent, // 7c627896 ShareOptions, // 800c3a4e - StatusBar, // f95dbb76 + StatusBar, // 5748d574 StatusBarAnimation, // 7fd047e6 - StatusBarInstance, // 416e9640 + StatusBarInstance, // de13e4a1 StatusBarProps, // c2a44d88 StatusBarStyle, // 78f53eea StyleProp, // fa0e9b4a - StyleSheet, // e734acd4 + StyleSheet, // 8f9da31a SubmitBehavior, // c4ddf490 Switch, // f495bab3 SwitchChangeEvent, // 899635b1 @@ -5973,15 +5982,15 @@ export { TouchableNativeFeedback, // fe739e82 TouchableNativeFeedbackInstance, // 0877e3e4 TouchableNativeFeedbackProps, // 1d0c2f30 - TouchableOpacity, // fe716ffc + TouchableOpacity, // ade59062 TouchableOpacityInstance, // b186055b - TouchableOpacityProps, // a3b32b69 + TouchableOpacityProps, // 98f8b9b4 TouchableWithoutFeedback, // ed159ba7 TouchableWithoutFeedbackProps, // e613ed05 TransformsStyle, // 65e70f18 TurboModule, // dfe29706 TurboModuleRegistry, // 4ace6db2 - UIManager, // afbcdf05 + UIManager, // 38bf2d34 UTFSequence, // ad625158 Vibration, // 31e4bbf8 View, // 3e72139a @@ -5993,10 +6002,10 @@ export { VirtualViewMode, // 6be59722 VirtualizedList, // 68c7345e VirtualizedListInstance, // 423ee7c0 - VirtualizedListProps, // f51f4a42 + VirtualizedListProps, // 47c47ba6 VirtualizedSectionList, // 9fd9cd61 VirtualizedSectionListInstance, // 12b706d5 - VirtualizedSectionListProps, // 8210f30a + VirtualizedSectionListProps, // 9775ebce WrapperComponentProvider, // 9ef54e61 codegenNativeCommands, // 628a7c0a codegenNativeComponent, // 32a1bca6 @@ -6004,9 +6013,9 @@ export { processColor, // 6e877698 registerCallableModule, // 839c8cfe requireNativeComponent, // aa36a6dd - useAnimatedColor, // a9dffd9f - useAnimatedValue, // 25733d13 - useAnimatedValueXY, // 04c70878 + useAnimatedColor, // d8b66fcd + useAnimatedValue, // 2386043c + useAnimatedValueXY, // 5b66327f useColorScheme, // d585efdb usePressability, // 782138ed useWindowDimensions, // bb4b683f diff --git a/packages/react-native/src/private/devsupport/devmenu/elementinspector/BoxInspector.js b/packages/react-native/src/private/devsupport/devmenu/elementinspector/BoxInspector.js index 59aa4c801a40..9565d23693de 100644 --- a/packages/react-native/src/private/devsupport/devmenu/elementinspector/BoxInspector.js +++ b/packages/react-native/src/private/devsupport/devmenu/elementinspector/BoxInspector.js @@ -61,10 +61,10 @@ type BoxContainerProps = Readonly<{ title: string, titleStyle?: TextStyleProp, box: Readonly<{ - top: number, - left: number, - right: number, - bottom: number, + top: number | string, + left: number | string, + right: number | string, + bottom: number | string, }>, children: React.Node, }>; diff --git a/packages/react-native/src/private/devsupport/devmenu/elementinspector/ElementBox.js b/packages/react-native/src/private/devsupport/devmenu/elementinspector/ElementBox.js index 08b4e9704ca0..a16c4fcec91c 100644 --- a/packages/react-native/src/private/devsupport/devmenu/elementinspector/ElementBox.js +++ b/packages/react-native/src/private/devsupport/devmenu/elementinspector/ElementBox.js @@ -16,8 +16,6 @@ import type {InspectedElementFrame} from './Inspector'; import * as React from 'react'; const View = require('../../../../../Libraries/Components/View/View').default; -const flattenStyle = - require('../../../../../Libraries/StyleSheet/flattenStyle').default; const StyleSheet = require('../../../../../Libraries/StyleSheet/StyleSheet').default; const Dimensions = @@ -31,9 +29,10 @@ type Props = Readonly<{ }>; function ElementBox({frame, style}: Props): React.Node { - const flattenedStyle = flattenStyle(style) || {}; - let margin: ?Readonly