From 5fdcd23aaa30a13eead12b7661a3a5903c6837f1 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Tue, 13 Sep 2022 13:33:43 -0400 Subject: [PATCH] Flow: upgrade to 0.140 (#25252) This update range includes: - `types_first` ([blog](https://flow.org/en/docs/lang/types-first/), all exports need annotated types) is default. I disabled this for now to make that change incremental. - Generics that escape the scope they are defined in are an error. I fixed some with explicit type annotations and some are suppressed that I didn't easily figure out. --- package.json | 2 +- packages/react-cache/src/LRU.js | 11 ++++++-- packages/react-cache/src/ReactCacheOld.js | 1 + .../react-dom/src/client/ReactDOMInput.js | 1 + .../src/server/ReactDOMFizzServerNode.js | 3 ++- .../src/legacy-events/accumulate.js | 2 ++ .../src/legacy-events/forEachAccumulated.js | 1 + .../src/ReactFiberClassUpdateQueue.new.js | 1 + .../src/ReactFiberClassUpdateQueue.old.js | 1 + .../src/ReactFiberHooks.new.js | 25 +++++++++++++------ .../src/ReactFiberHooks.old.js | 25 +++++++++++++------ .../react-refresh/src/ReactFreshRuntime.js | 1 + .../src/ReactFlightDOMServerNode.js | 3 ++- .../src/useSyncExternalStoreShimClient.js | 5 +++- scripts/flow/config/flowconfig | 3 ++- yarn.lock | 8 +++--- 16 files changed, 68 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index f2444f3cc2e17..b440056f54b82 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "eslint-plugin-react-internal": "link:./scripts/eslint-rules", "fbjs-scripts": "1.2.0", "filesize": "^6.0.1", - "flow-bin": "^0.132", + "flow-bin": "^0.140", "glob": "^7.1.6", "glob-stream": "^6.1.0", "google-closure-compiler": "^20200517.0.0", diff --git a/packages/react-cache/src/LRU.js b/packages/react-cache/src/LRU.js index 9a90cc8a3ede7..8462849c4463b 100644 --- a/packages/react-cache/src/LRU.js +++ b/packages/react-cache/src/LRU.js @@ -23,7 +23,14 @@ type Entry = { next: Entry, }; -export function createLRU(limit: number) { +type LRU = { + add(value: Object, onDelete: () => mixed): Entry, + update(entry: Entry, newValue: T): void, + access(entry: Entry): T, + setLimit(newLimit: number): void, +}; + +export function createLRU(limit: number): LRU { let LIMIT = limit; // Circular, doubly-linked list @@ -135,7 +142,7 @@ export function createLRU(limit: number) { return entry.value; } - function setLimit(newLimit: number) { + function setLimit(newLimit: number): void { LIMIT = newLimit; scheduleCleanUp(); } diff --git a/packages/react-cache/src/ReactCacheOld.js b/packages/react-cache/src/ReactCacheOld.js index 8781899dc2ae7..9693113b49d0e 100644 --- a/packages/react-cache/src/ReactCacheOld.js +++ b/packages/react-cache/src/ReactCacheOld.js @@ -122,6 +122,7 @@ function accessResult( status: Pending, value: thenable, }; + // $FlowFixMe[escaped-generic] discovered when updating Flow const newEntry = lru.add(newResult, deleteEntry.bind(null, resource, key)); entriesForResource.set(key, newEntry); return newResult; diff --git a/packages/react-dom/src/client/ReactDOMInput.js b/packages/react-dom/src/client/ReactDOMInput.js index a4b8dede45a73..8d9ea1f45a431 100644 --- a/packages/react-dom/src/client/ReactDOMInput.js +++ b/packages/react-dom/src/client/ReactDOMInput.js @@ -177,6 +177,7 @@ export function updateWrapper(element: Element, props: Object) { if (value != null) { if (type === 'number') { if ( + // $FlowFixMe[incompatible-type] (value === 0 && node.value === '') || // We explicitly want to coerce to number here if possible. // eslint-disable-next-line diff --git a/packages/react-dom/src/server/ReactDOMFizzServerNode.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js index facfe3f80c33d..089d24bf7b277 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerNode.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js @@ -10,6 +10,7 @@ import type {ReactNodeList} from 'shared/ReactTypes'; import type {Writable} from 'stream'; import type {BootstrapScriptDescriptor} from './ReactDOMServerFormatConfig'; +import type {Destination} from 'react-server/src/ReactServerStreamConfigNode'; import ReactVersion from 'shared/ReactVersion'; @@ -25,7 +26,7 @@ import { createRootFormatContext, } from './ReactDOMServerFormatConfig'; -function createDrainHandler(destination, request) { +function createDrainHandler(destination: Destination, request) { return () => startFlowing(request, destination); } diff --git a/packages/react-native-renderer/src/legacy-events/accumulate.js b/packages/react-native-renderer/src/legacy-events/accumulate.js index 0e19adc919e57..6d43ada04f0ef 100644 --- a/packages/react-native-renderer/src/legacy-events/accumulate.js +++ b/packages/react-native-renderer/src/legacy-events/accumulate.js @@ -33,6 +33,8 @@ function accumulate( // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). if (isArray(current)) { + /* $FlowFixMe[incompatible-return] if `current` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ return current.concat(next); } diff --git a/packages/react-native-renderer/src/legacy-events/forEachAccumulated.js b/packages/react-native-renderer/src/legacy-events/forEachAccumulated.js index 369be5605cc47..877f026419f78 100644 --- a/packages/react-native-renderer/src/legacy-events/forEachAccumulated.js +++ b/packages/react-native-renderer/src/legacy-events/forEachAccumulated.js @@ -22,6 +22,7 @@ function forEachAccumulated( scope: ?any, ) { if (Array.isArray(arr)) { + // $FlowFixMe[incompatible-call] if `T` is an array, `cb` cannot be called arr.forEach(cb, scope); } else if (arr) { cb.call(scope, arr); diff --git a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js index a38d9aaecb8c6..5bdc8fc6a82a0 100644 --- a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js +++ b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js @@ -476,6 +476,7 @@ export function processUpdateQueue( hasForceUpdate = false; if (__DEV__) { + // $FlowFixMe[escaped-generic] discovered when updating Flow currentlyProcessingQueue = queue.shared; } diff --git a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.old.js b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.old.js index 94908d61df5e3..bdff2ea93e704 100644 --- a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.old.js +++ b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.old.js @@ -476,6 +476,7 @@ export function processUpdateQueue( hasForceUpdate = false; if (__DEV__) { + // $FlowFixMe[escaped-generic] discovered when updating Flow currentlyProcessingQueue = queue.shared; } diff --git a/packages/react-reconciler/src/ReactFiberHooks.new.js b/packages/react-reconciler/src/ReactFiberHooks.new.js index da2254a682eb5..3f45ec61434a9 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.new.js +++ b/packages/react-reconciler/src/ReactFiberHooks.new.js @@ -160,7 +160,7 @@ export type Effect = { tag: HookFlags, create: () => (() => void) | void, destroy: (() => void) | void, - deps: Array | null, + deps: Array | void | null, next: Effect, }; @@ -1539,7 +1539,7 @@ function updateStoreInstance( } } -function subscribeToStore(fiber, inst, subscribe) { +function subscribeToStore(fiber, inst: StoreInstance, subscribe) { const handleStoreChange = () => { // The store changed. Check if the snapshot changed since the last time we // read from the store. @@ -1552,7 +1552,7 @@ function subscribeToStore(fiber, inst, subscribe) { return subscribe(handleStoreChange); } -function checkIfSnapshotChanged(inst) { +function checkIfSnapshotChanged(inst: StoreInstance): boolean { const latestGetSnapshot = inst.getSnapshot; const prevValue = inst.value; try { @@ -1609,7 +1609,7 @@ function rerenderState( return rerenderReducer(basicStateReducer, (initialState: any)); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, destroy, deps: Array | void | null) { const effect: Effect = { tag, create, @@ -1728,7 +1728,12 @@ function updateRef(initialValue: T): {current: T} { return hook.memoizedState; } -function mountEffectImpl(fiberFlags, hookFlags, create, deps): void { +function mountEffectImpl( + fiberFlags, + hookFlags, + create, + deps: Array | void | null, +): void { const hook = mountWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; currentlyRenderingFiber.flags |= fiberFlags; @@ -1740,7 +1745,12 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps): void { ); } -function updateEffectImpl(fiberFlags, hookFlags, create, deps): void { +function updateEffectImpl( + fiberFlags, + hookFlags, + create, + deps: Array | void | null, +): void { const hook = updateWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; let destroy = undefined; @@ -2395,7 +2405,7 @@ function entangleTransitionUpdate( } } -function markUpdateInDevTools(fiber, lane, action) { +function markUpdateInDevTools(fiber, lane, action: A) { if (__DEV__) { if (enableDebugTracing) { if (fiber.mode & DebugTracingMode) { @@ -2490,6 +2500,7 @@ const HooksDispatcherOnMount: Dispatcher = { if (enableCache) { (HooksDispatcherOnMount: Dispatcher).getCacheSignal = getCacheSignal; (HooksDispatcherOnMount: Dispatcher).getCacheForType = getCacheForType; + // $FlowFixMe[escaped-generic] discovered when updating Flow (HooksDispatcherOnMount: Dispatcher).useCacheRefresh = mountRefresh; } if (enableUseHook) { diff --git a/packages/react-reconciler/src/ReactFiberHooks.old.js b/packages/react-reconciler/src/ReactFiberHooks.old.js index 4e53c1b2545dc..5495a2992b787 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.old.js +++ b/packages/react-reconciler/src/ReactFiberHooks.old.js @@ -160,7 +160,7 @@ export type Effect = { tag: HookFlags, create: () => (() => void) | void, destroy: (() => void) | void, - deps: Array | null, + deps: Array | void | null, next: Effect, }; @@ -1539,7 +1539,7 @@ function updateStoreInstance( } } -function subscribeToStore(fiber, inst, subscribe) { +function subscribeToStore(fiber, inst: StoreInstance, subscribe) { const handleStoreChange = () => { // The store changed. Check if the snapshot changed since the last time we // read from the store. @@ -1552,7 +1552,7 @@ function subscribeToStore(fiber, inst, subscribe) { return subscribe(handleStoreChange); } -function checkIfSnapshotChanged(inst) { +function checkIfSnapshotChanged(inst: StoreInstance): boolean { const latestGetSnapshot = inst.getSnapshot; const prevValue = inst.value; try { @@ -1609,7 +1609,7 @@ function rerenderState( return rerenderReducer(basicStateReducer, (initialState: any)); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, destroy, deps: Array | void | null) { const effect: Effect = { tag, create, @@ -1728,7 +1728,12 @@ function updateRef(initialValue: T): {current: T} { return hook.memoizedState; } -function mountEffectImpl(fiberFlags, hookFlags, create, deps): void { +function mountEffectImpl( + fiberFlags, + hookFlags, + create, + deps: Array | void | null, +): void { const hook = mountWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; currentlyRenderingFiber.flags |= fiberFlags; @@ -1740,7 +1745,12 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps): void { ); } -function updateEffectImpl(fiberFlags, hookFlags, create, deps): void { +function updateEffectImpl( + fiberFlags, + hookFlags, + create, + deps: Array | void | null, +): void { const hook = updateWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; let destroy = undefined; @@ -2395,7 +2405,7 @@ function entangleTransitionUpdate( } } -function markUpdateInDevTools(fiber, lane, action) { +function markUpdateInDevTools(fiber, lane, action: A) { if (__DEV__) { if (enableDebugTracing) { if (fiber.mode & DebugTracingMode) { @@ -2490,6 +2500,7 @@ const HooksDispatcherOnMount: Dispatcher = { if (enableCache) { (HooksDispatcherOnMount: Dispatcher).getCacheSignal = getCacheSignal; (HooksDispatcherOnMount: Dispatcher).getCacheForType = getCacheForType; + // $FlowFixMe[escaped-generic] discovered when updating Flow (HooksDispatcherOnMount: Dispatcher).useCacheRefresh = mountRefresh; } if (enableUseHook) { diff --git a/packages/react-refresh/src/ReactFreshRuntime.js b/packages/react-refresh/src/ReactFreshRuntime.js index f440275c2a7ac..99d4d03199d70 100644 --- a/packages/react-refresh/src/ReactFreshRuntime.js +++ b/packages/react-refresh/src/ReactFreshRuntime.js @@ -654,6 +654,7 @@ export function createSignatureFunctionForTransform() { // in HOC chains like _s(hoc1(_s(hoc2(_s(actualFunction))))). if (!savedType) { // We're in the innermost call, so this is the actual type. + // $FlowFixMe[escaped-generic] discovered when updating Flow savedType = type; hasCustomHooks = typeof getCustomHooks === 'function'; } diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js index addf3758c12a8..88c6b85337dc7 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js @@ -8,6 +8,7 @@ */ import type {ReactModel} from 'react-server/src/ReactFlightServer'; +import type {Destination} from 'react-server/src/ReactServerStreamConfigNode'; import type {BundlerConfig} from './ReactFlightServerWebpackBundlerConfig'; import type {Writable} from 'stream'; import type {ServerContextJSONValue} from 'shared/ReactTypes'; @@ -19,7 +20,7 @@ import { abort, } from 'react-server/src/ReactFlightServer'; -function createDrainHandler(destination, request) { +function createDrainHandler(destination: Destination, request) { return () => startFlowing(request, destination); } diff --git a/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js b/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js index 4eb764091ae00..99cb6c65725c6 100644 --- a/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js +++ b/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js @@ -128,7 +128,10 @@ export function useSyncExternalStore( return value; } -function checkIfSnapshotChanged(inst) { +function checkIfSnapshotChanged(inst: { + value: T, + getSnapshot: () => T, +}): boolean { const latestGetSnapshot = inst.getSnapshot; const prevValue = inst.value; try { diff --git a/scripts/flow/config/flowconfig b/scripts/flow/config/flowconfig index 9b47998da9880..b5639113089a0 100644 --- a/scripts/flow/config/flowconfig +++ b/scripts/flow/config/flowconfig @@ -45,9 +45,10 @@ esproposal.class_instance_fields=enable esproposal.optional_chaining=enable exact_by_default=true munge_underscores=false +types_first=false # Substituted by createFlowConfig.js: %REACT_RENDERER_FLOW_OPTIONS% [version] -^0.132.0 +^0.140.0 diff --git a/yarn.lock b/yarn.lock index 2d71503a7a340..a3dc1a988861d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7914,10 +7914,10 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== -flow-bin@^0.132: - version "0.132.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.132.0.tgz#8bf80a79630db24bd1422dc2cc4b5e97f97ccb98" - integrity sha512-S1g/vnAyNaLUdajmuUHCMl30qqye12gS6mr4LVyswf1k+JDF4efs6SfKmptuvnpitF3LGCVf0TIffChP8ljwnw== +flow-bin@^0.140: + version "0.140.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.140.0.tgz#bf1a2984a0e5604daa0d1e0432138d9897af65bb" + integrity sha512-9P/VciKACXocClhLiDg/p1ntYmgCEEc9QrNOoTqTi2SEdEZDTiAmJLONRJfw4uglPVRZ1p/esWF9KlbZiuxqVw== fluent-syntax@0.13.0: version "0.13.0"