diff --git a/package.json b/package.json index b1b187b9edd8..bd408294edbf 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "fbjs": "^0.8.16", "fbjs-scripts": "^0.6.0", "filesize": "^3.5.6", - "flow-bin": "^0.61.0", + "flow-bin": "^0.72.0", "flow-coverage-report": "^0.4.0", "git-branch": "^0.3.0", "glob": "^6.0.4", diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 4526bcf316d9..d65f09641ef9 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -53,9 +53,11 @@ let didWarnAboutUnstableCreatePortal = false; if (__DEV__) { if ( typeof Map !== 'function' || + // $FlowIssue Flow incorrectly thinks Map has no prototype Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || + // $FlowIssue Flow incorrectly thinks Set has no prototype Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function' diff --git a/packages/react-dom/src/client/ReactDOMFiberComponent.js b/packages/react-dom/src/client/ReactDOMFiberComponent.js index 4c3c7a9c1dd3..3c9e802b6e34 100644 --- a/packages/react-dom/src/client/ReactDOMFiberComponent.js +++ b/packages/react-dom/src/client/ReactDOMFiberComponent.js @@ -432,7 +432,11 @@ export function setInitialProperties( const isCustomComponentTag = isCustomComponent(tag, rawProps); if (__DEV__) { validatePropertiesInDevelopment(tag, rawProps); - if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { + if ( + isCustomComponentTag && + !didWarnShadyDOM && + (domElement: any).shadyRoot + ) { warning( false, '%s is using shady DOM. Using shady DOM with React can ' + @@ -820,7 +824,11 @@ export function diffHydratedProperties( suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true; isCustomComponentTag = isCustomComponent(tag, rawProps); validatePropertiesInDevelopment(tag, rawProps); - if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { + if ( + isCustomComponentTag && + !didWarnShadyDOM && + (domElement: any).shadyRoot + ) { warning( false, '%s is using shady DOM. Using shady DOM with React can ' + diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js index 15385db2eec1..9d06c8f26802 100644 --- a/packages/react-dom/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom/src/client/ReactDOMHostConfig.js @@ -30,6 +30,7 @@ export type Props = { children?: mixed, hidden?: boolean, suppressHydrationWarning?: boolean, + dangerouslySetInnerHTML?: mixed, }; export type Container = Element | Document; export type Instance = Element; diff --git a/packages/react-dom/src/client/inputValueTracking.js b/packages/react-dom/src/client/inputValueTracking.js index 732a77beee89..4ccc80ac85b1 100644 --- a/packages/react-dom/src/client/inputValueTracking.js +++ b/packages/react-dom/src/client/inputValueTracking.js @@ -63,20 +63,21 @@ function trackValueOnNode(node: any): ?ValueTracker { // (needed for certain tests that spyOn input values and Safari) if ( node.hasOwnProperty(valueField) || + typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function' ) { return; } - + const {get, set} = descriptor; Object.defineProperty(node, valueField, { configurable: true, get: function() { - return descriptor.get.call(this); + return get.call(this); }, set: function(value) { currentValue = '' + value; - descriptor.set.call(this, value); + set.call(this, value); }, }); // We could've passed this the first time diff --git a/packages/react-dom/src/events/TapEventPlugin.js b/packages/react-dom/src/events/TapEventPlugin.js index e1baab05eac4..9c4aab6e6cd6 100644 --- a/packages/react-dom/src/events/TapEventPlugin.js +++ b/packages/react-dom/src/events/TapEventPlugin.js @@ -119,10 +119,11 @@ const pointerEvents = [ TOP_POINTER_UP, ]; -const dependencies = [TOP_MOUSE_DOWN, TOP_MOUSE_MOVE, TOP_MOUSE_UP].concat( - touchEvents, - pointerEvents, -); +const dependencies: Array = [ + TOP_MOUSE_DOWN, + TOP_MOUSE_MOVE, + TOP_MOUSE_UP, +].concat(touchEvents, pointerEvents); const eventTypes = { touchTap: { diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 757212fe2000..3f0146d4c128 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -63,9 +63,11 @@ function findNodeHandle(componentOrHandle: any): ?number { if (hostInstance == null) { return hostInstance; } - if (hostInstance.canonical) { + // TODO: the code is right but the types here are wrong. + // https://github.com/facebook/react/pull/12863 + if ((hostInstance: any).canonical) { // Fabric - return (hostInstance.canonical: any)._nativeTag; + return (hostInstance: any).canonical._nativeTag; } return hostInstance._nativeTag; } diff --git a/packages/react-native-renderer/src/ReactNativeFrameScheduling.js b/packages/react-native-renderer/src/ReactNativeFrameScheduling.js index ee88fcf5fa20..f4dd2b2e3f0d 100644 --- a/packages/react-native-renderer/src/ReactNativeFrameScheduling.js +++ b/packages/react-native-renderer/src/ReactNativeFrameScheduling.js @@ -49,12 +49,13 @@ function scheduleDeferredCallback( ): number { // We assume only one callback is scheduled at a time b'c that's how Fiber works. scheduledCallback = callback; - return setTimeout(setTimeoutCallback, 1); + const timeoutId = setTimeout(setTimeoutCallback, 1); + return (timeoutId: any); // Timeouts are always numbers on RN } function cancelDeferredCallback(callbackID: number) { scheduledCallback = null; - clearTimeout(callbackID); + clearTimeout((callbackID: any)); // Timeouts are always numbers on RN } export {now, scheduleDeferredCallback, cancelDeferredCallback}; diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index a66548fdc902..50d63de4fa17 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -66,9 +66,9 @@ function findNodeHandle(componentOrHandle: any): ?number { if (hostInstance == null) { return hostInstance; } - if (hostInstance.canonical) { + if ((hostInstance: any).canonical) { // Fabric - return (hostInstance.canonical: any)._nativeTag; + return (hostInstance: any).canonical._nativeTag; } return hostInstance._nativeTag; } diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 950f0deec29c..873dc8879934 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -23,7 +23,7 @@ import emptyObject from 'fbjs/lib/emptyObject'; import expect from 'expect'; type Container = {rootID: string, children: Array}; -type Props = {prop: any, hidden?: boolean}; +type Props = {prop: any, hidden?: boolean, children?: mixed}; type Instance = {| type: string, id: number, diff --git a/packages/react-reconciler/src/ReactChildFiber.js b/packages/react-reconciler/src/ReactChildFiber.js index d3140340c261..ae19577aa29c 100644 --- a/packages/react-reconciler/src/ReactChildFiber.js +++ b/packages/react-reconciler/src/ReactChildFiber.js @@ -151,6 +151,7 @@ function coerceRef( if ( current !== null && current.ref !== null && + typeof current.ref === 'function' && current.ref._stringRef === stringRef ) { return current.ref; @@ -901,18 +902,15 @@ function ChildReconciler(shouldTrackSideEffects) { if (__DEV__) { // Warn about using Maps as children - if (typeof newChildrenIterable.entries === 'function') { - const possibleMap = (newChildrenIterable: any); - if (possibleMap.entries === iteratorFn) { - warning( - didWarnAboutMaps, - 'Using Maps as children is unsupported and will likely yield ' + - 'unexpected results. Convert it to a sequence/iterable of keyed ' + - 'ReactElements instead.%s', - getCurrentFiberStackAddendum(), - ); - didWarnAboutMaps = true; - } + if ((newChildrenIterable: any).entries === iteratorFn) { + warning( + didWarnAboutMaps, + 'Using Maps as children is unsupported and will likely yield ' + + 'unexpected results. Convert it to a sequence/iterable of keyed ' + + 'ReactElements instead.%s', + getCurrentFiberStackAddendum(), + ); + didWarnAboutMaps = true; } // First, validate keys. diff --git a/packages/react-reconciler/src/ReactFiberContext.js b/packages/react-reconciler/src/ReactFiberContext.js index edbe7b2fa50f..8faf15464206 100644 --- a/packages/react-reconciler/src/ReactFiberContext.js +++ b/packages/react-reconciler/src/ReactFiberContext.js @@ -137,7 +137,7 @@ function pushTopLevelContextObject( didChange: boolean, ): void { invariant( - contextStackCursor.cursor == null, + contextStackCursor.current === emptyObject, 'Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.', ); diff --git a/packages/react-scheduler/src/ReactScheduler.js b/packages/react-scheduler/src/ReactScheduler.js index d1c6eab14d08..9da8fd975d70 100644 --- a/packages/react-scheduler/src/ReactScheduler.js +++ b/packages/react-scheduler/src/ReactScheduler.js @@ -60,14 +60,20 @@ let scheduleWork: ( callback: FrameCallbackType, options?: {timeout: number}, ) => number; -let cancelScheduledWork: (callbackID: number) => void; +let cancelScheduledWork: (callbackId: number) => void; if (!ExecutionEnvironment.canUseDOM) { + let callbackIdCounter = 0; + // Timeouts are objects in Node. + // For consistency, we'll use numbers in the public API anyway. + const timeoutIds: {[number]: TimeoutID} = {}; + scheduleWork = function( callback: FrameCallbackType, options?: {timeout: number}, ): number { - return setTimeout(() => { + const callbackId = callbackIdCounter++; + const timeoutId = setTimeout(() => { callback({ timeRemaining() { return Infinity; @@ -75,9 +81,13 @@ if (!ExecutionEnvironment.canUseDOM) { didTimeout: false, }); }); + timeoutIds[callbackId] = timeoutId; + return callbackId; }; - cancelScheduledWork = function(timeoutID: number) { - clearTimeout(timeoutID); + cancelScheduledWork = function(callbackId: number) { + const timeoutId = timeoutIds[callbackId]; + delete timeoutIds[callbackId]; + clearTimeout(timeoutId); }; } else { // We keep callbacks in a queue. diff --git a/packages/react-test-renderer/src/ReactTestRenderer.js b/packages/react-test-renderer/src/ReactTestRenderer.js index ad612d6ddeeb..3fff46d81898 100644 --- a/packages/react-test-renderer/src/ReactTestRenderer.js +++ b/packages/react-test-renderer/src/ReactTestRenderer.js @@ -414,7 +414,7 @@ const ReactTestRendererFiber = { const entry = { root: undefined, // makes flow happy // we define a 'getter' for 'root' below using 'Object.defineProperty' - toJSON() { + toJSON(): Array | ReactTestRendererNode | null { if (root == null || root.current == null || container == null) { return null; } diff --git a/scripts/flow/config/flowconfig b/scripts/flow/config/flowconfig index b0e77d36f635..cd0c4af1b15a 100644 --- a/scripts/flow/config/flowconfig +++ b/scripts/flow/config/flowconfig @@ -28,7 +28,6 @@ untyped-type-import=error [options] esproposal.class_static_fields=enable esproposal.class_instance_fields=enable -unsafe.enable_getters_and_setters=true # Substituted by createFlowConfig.js: %REACT_RENDERER_FLOW_OPTIONS% @@ -46,4 +45,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError [version] -^0.61.0 \ No newline at end of file +^0.72.0 \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 710312cbeba7..6ddc40c4f540 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2420,9 +2420,9 @@ flow-annotation-check@1.3.1: glob "7.1.1" load-pkg "^3.0.1" -flow-bin@^0.61.0: - version "0.61.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.61.0.tgz#d0473a8c35dbbf4de573823f4932124397d32d35" +flow-bin@^0.72.0: + version "0.72.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.72.0.tgz#12051180fb2db7ccb728fefe67c77e955e92a44d" flow-coverage-report@^0.4.0: version "0.4.0"