Compare commits

..

2 Commits

Author SHA1 Message Date
Lauren Tan
00b49e3d79 [flow] Upgrade from 0.280 -> 0.281
Major changes in Flow 0.281:
- $FlowFixMe comments now require explicit error codes (e.g., $FlowFixMe[incompatible-type])
- Changed all bare $FlowFixMe to include appropriate error codes
- Changed $FlowIgnore to $FlowFixMe where needed
- Fixed stream types to have cancel() return Promise<void> instead of void
- Added pseudoElement property to KeyframeEffect type
- Added suppressions for Proxy handler variance issues
- Fixed various type errors across the codebase
2025-12-08 15:39:51 -08:00
Lauren Tan
76dc3c0ba9 [flow] Upgrade from 0.279 -> 0.280
Flow 0.280 introduced stricter type checking for `incompatible-type` errors,
requiring additional $FlowFixMe suppressions alongside existing ones. Changes:

- Made `QueuingStrategy` properties optional in streams.js
- Made all properties optional in Web Animations API types (EffectTiming,
  KeyframeAnimationOptions, etc.)
- Added `$FlowFixMe[incompatible-type]` alongside existing suppressions in
  multiple files where Flow now reports additional type mismatches
2025-12-08 15:27:45 -08:00
44 changed files with 163 additions and 142 deletions

View File

@@ -1,9 +1,6 @@
# react runtime
build
# flow-typed generated files use Flow syntax Prettier can't parse
flow-typed
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/firefox/build

View File

@@ -75,8 +75,8 @@
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
"fbjs-scripts": "^3.0.1",
"filesize": "^6.0.1",
"flow-bin": "^0.280.0",
"flow-remove-types": "^2.280.0",
"flow-bin": "^0.281.0",
"flow-remove-types": "^2.281.0",
"flow-typed": "^4.1.1",
"glob": "^7.1.6",
"glob-stream": "^6.1.0",

View File

@@ -35,7 +35,7 @@ export function bindToConsole(
case 'groupEnd':
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return bind.apply(console[methodName], [console].concat(args)); // eslint-disable-line react-internal/no-production-logging
}
case 'assert': {
@@ -68,6 +68,7 @@ export function bindToConsole(
// The "this" binding in the "bind";
newArgs.unshift(console);
// $FlowFixMe
// $FlowFixMe[incompatible-type]
// $FlowFixMe[invalid-computed-prop]
return bind.apply(console[methodName], newArgs); // eslint-disable-line react-internal/no-production-logging
}

View File

@@ -25,7 +25,7 @@ export function bindToConsole(
case 'groupEnd':
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return bind.apply(console[methodName], [console].concat(args)); // eslint-disable-line react-internal/no-production-logging
}
case 'assert': {
@@ -49,6 +49,7 @@ export function bindToConsole(
// The "this" binding in the "bind";
newArgs.unshift(console);
// $FlowFixMe
// $FlowFixMe[incompatible-type]
// $FlowFixMe[invalid-computed-prop]
return bind.apply(console[methodName], newArgs); // eslint-disable-line react-internal/no-production-logging
}

View File

@@ -36,7 +36,7 @@ export function bindToConsole(
case 'groupEnd':
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return bind.apply(console[methodName], [console].concat(args)); // eslint-disable-line react-internal/no-production-logging
}
case 'assert': {
@@ -69,6 +69,7 @@ export function bindToConsole(
// The "this" binding in the "bind";
newArgs.unshift(console);
// $FlowFixMe
// $FlowFixMe[incompatible-type]
// $FlowFixMe[invalid-computed-prop]
return bind.apply(console[methodName], newArgs); // eslint-disable-line react-internal/no-production-logging
}

View File

@@ -283,12 +283,12 @@ ReactPromise.prototype.then = function <T>(
const rejectCallback = reject;
const wrapperPromise: Promise<T> = new Promise((res, rej) => {
resolve = value => {
// $FlowFixMe
// $FlowFixMe[prop-missing]
wrapperPromise._debugInfo = this._debugInfo;
res(value);
};
reject = reason => {
// $FlowFixMe
// $FlowFixMe[prop-missing]
wrapperPromise._debugInfo = this._debugInfo;
rej(reason);
};
@@ -3922,7 +3922,7 @@ function initializeDebugInfo(
}
if (debugInfo.owner == null && response._debugRootOwner != null) {
const componentInfoOrAsyncInfo: ReactComponentInfo | ReactAsyncInfo =
// $FlowFixMe: By narrowing `owner` to `null`, we narrowed `debugInfo` to `ReactComponentInfo`
// $FlowFixMe[incompatible-type]: By narrowing `owner` to `null`, we narrowed `debugInfo` to `ReactComponentInfo`
debugInfo;
// $FlowFixMe[cannot-write]
componentInfoOrAsyncInfo.owner = response._debugRootOwner;
@@ -4268,7 +4268,7 @@ function logComponentInfo(
childrenEndTime: number,
isLastComponent: boolean,
): void {
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-use]: Refined.
if (
isLastComponent &&
root.status === ERRORED &&
@@ -4447,7 +4447,7 @@ function flushComponentPerformance(
if (componentEndTime > childrenEndTime) {
childrenEndTime = componentEndTime;
}
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
const componentInfo: ReactComponentInfo = candidateInfo;
logComponentInfo(
response,
@@ -4471,7 +4471,7 @@ function flushComponentPerformance(
if (endTime > childrenEndTime) {
childrenEndTime = endTime;
}
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
const asyncInfo: ReactAsyncInfo = candidateInfo;
const env = response._rootEnvironmentName;
const promise = asyncInfo.awaited.value;
@@ -4534,7 +4534,7 @@ function flushComponentPerformance(
if (componentEndTime > childrenEndTime) {
childrenEndTime = componentEndTime;
}
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
const componentInfo: ReactComponentInfo = candidateInfo;
const env = response._rootEnvironmentName;
logComponentAborted(

View File

@@ -12,11 +12,10 @@ import {TextDecoder} from 'util';
export type StringDecoder = TextDecoder;
export function createStringDecoder(): StringDecoder {
// $FlowFixMe[incompatible-type] Flow's TextDecoder libdef requires options but it's optional at runtime
return new TextDecoder();
}
const decoderOptions = {stream: true};
const decoderOptions: {stream?: boolean, ...} = {stream: true};
export function readPartialStringChunk(
decoder: StringDecoder,

View File

@@ -3770,7 +3770,7 @@ export function attach(
start,
end,
value: promise,
// $FlowFixMe: This field doesn't usually take a Fiber but we're only using inside this file.
// $FlowFixMe[incompatible-type]: This field doesn't usually take a Fiber but we're only using inside this file.
owner: fiber, // Allow linking to the <link> if it's not filtered.
};
if (byteSize > 0) {
@@ -3779,7 +3779,7 @@ export function attach(
}
const asyncInfo: ReactAsyncInfo = {
awaited: ioInfo,
// $FlowFixMe: This field doesn't usually take a Fiber but we're only using inside this file.
// $FlowFixMe[incompatible-type]: This field doesn't usually take a Fiber but we're only using inside this file.
owner: fiber._debugOwner == null ? null : fiber._debugOwner,
debugStack: fiber._debugStack == null ? null : fiber._debugStack,
debugTask: fiber._debugTask == null ? null : fiber._debugTask,
@@ -3886,7 +3886,7 @@ export function attach(
start,
end,
value: promise,
// $FlowFixMe: This field doesn't usually take a Fiber but we're only using inside this file.
// $FlowFixMe[incompatible-type]: This field doesn't usually take a Fiber but we're only using inside this file.
owner: fiber, // Allow linking to the <link> if it's not filtered.
};
if (byteSize > 0) {
@@ -3895,7 +3895,7 @@ export function attach(
}
const asyncInfo: ReactAsyncInfo = {
awaited: ioInfo,
// $FlowFixMe: This field doesn't usually take a Fiber but we're only using inside this file.
// $FlowFixMe[incompatible-type]: This field doesn't usually take a Fiber but we're only using inside this file.
owner: fiber._debugOwner == null ? null : fiber._debugOwner,
debugStack: fiber._debugStack == null ? null : fiber._debugStack,
debugTask: fiber._debugTask == null ? null : fiber._debugTask,
@@ -6053,7 +6053,7 @@ export function attach(
function getNearestMountedDOMNode(publicInstance: Element): null | Element {
let domNode: null | Element = publicInstance;
while (domNode && !publicInstanceToDevToolsInstanceMap.has(domNode)) {
// $FlowFixMe: In practice this is either null or Element.
// $FlowFixMe[incompatible-type]: In practice this is either null or Element.
domNode = domNode.parentNode;
}
return domNode;
@@ -8807,7 +8807,7 @@ export function attach(
return (instance.source = extractLocationFromComponentStack(lastLine));
}
// $FlowFixMe: refined.
// $FlowFixMe[incompatible-return]: refined.
return unresolvedSource;
}

View File

@@ -362,13 +362,13 @@ class Bridge<
this._messageQueue.push(event, payload);
if (!this._scheduledFlush) {
this._scheduledFlush = true;
// $FlowFixMe
// $FlowFixMe[cannot-resolve-name]
if (typeof devtoolsJestTestScheduler === 'function') {
// This exists just for our own jest tests.
// They're written in such a way that we can neither mock queueMicrotask
// because then we break React DOM and we can't not mock it because then
// we can't synchronously flush it. So they need to be rewritten.
// $FlowFixMe
// $FlowFixMe[cannot-resolve-name]
devtoolsJestTestScheduler(this._flush); // eslint-disable-line no-undef
} else {
queueMicrotask(this._flush);

View File

@@ -27,7 +27,7 @@ import Toggle from '../Toggle';
import type {HooksNode} from 'react-debug-tools/src/ReactDebugHooks';
import type {ChangeDescription} from './types';
// $FlowFixMe: Flow doesn't know about Intl.ListFormat
// $FlowFixMe[prop-missing]: Flow doesn't know about Intl.ListFormat
const hookListFormatter = new Intl.ListFormat('en', {
style: 'long',
type: 'conjunction',

View File

@@ -174,9 +174,9 @@ function SuspenseTreeContextController({children}: Props): React.Node {
let selectedTimelineID: null | number = null;
if (selectedTimelineStep !== null) {
selectedTimelineID = selectedTimelineStep.id;
// $FlowFixMe
// $FlowFixMe[incompatible-call]
while (removedIDs.has(selectedTimelineID)) {
// $FlowFixMe
// $FlowFixMe[incompatible-type]
selectedTimelineID = removedIDs.get(selectedTimelineID);
}
}

View File

@@ -94,7 +94,7 @@ function mountLegacyApp(App: () => React$Node) {
// $FlowFixMe[not-a-function]: These are removed in 19.
render(createElement(LegacyRender), container);
// $FlowFixMe: These are removed in 19.
// $FlowFixMe[not-a-function]: These are removed in 19.
unmountFunctions.push(() => unmountComponentAtNode(container));
}

View File

@@ -1562,7 +1562,7 @@ export function cancelViewTransitionName(
if (documentElement !== null) {
documentElement.animate(
{opacity: [0, 0], pointerEvents: ['none', 'none']},
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
{
duration: 0,
fill: 'forwards',
@@ -1599,7 +1599,7 @@ export function cancelRootViewTransitionName(rootContainer: Container): void {
documentElement.style.viewTransitionName = 'none';
documentElement.animate(
{opacity: [0, 0], pointerEvents: ['none', 'none']},
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
{
duration: 0,
fill: 'forwards',
@@ -1615,7 +1615,7 @@ export function cancelRootViewTransitionName(rootContainer: Container): void {
// whatever is below the animation.
documentElement.animate(
{width: [0, 0], height: [0, 0]},
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
{
duration: 0,
fill: 'forwards',
@@ -1799,7 +1799,7 @@ export function cloneRootViewTransitionContainer(
if (getComputedStyle(positionedAncestor).position !== 'static') {
break;
}
// $FlowFixMe: This is refined.
// $FlowFixMe[incompatible-type]: This is refined.
positionedAncestor = positionedAncestor.parentNode;
}
@@ -2001,12 +2001,10 @@ function cancelAllViewTransitionAnimations(scope: Element) {
// In Safari, we need to manually cancel all manually start animations
// or it'll block or interfer with future transitions.
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-type]
const animations = scope.getAnimations({subtree: true});
for (let i = 0; i < animations.length; i++) {
const anim = animations[i];
const effect: KeyframeEffect = (anim.effect: any);
// $FlowFixMe[prop-missing]
const pseudo: ?string = effect.pseudoElement;
if (
pseudo != null &&
@@ -2216,12 +2214,10 @@ export function startViewTransition(
const documentElement: Element = (ownerDocument.documentElement: any);
// Loop through all View Transition Animations.
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-type]
const animations = documentElement.getAnimations({subtree: true});
for (let i = 0; i < animations.length; i++) {
const animation = animations[i];
const effect: KeyframeEffect = (animation.effect: any);
// $FlowFixMe[prop-missing]
const pseudoElement: ?string = effect.pseudoElement;
if (
pseudoElement != null &&
@@ -2262,13 +2258,13 @@ export function startViewTransition(
height !== undefined
) {
// Replace the keyframes with ones that don't animate the width/height.
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
effect.setKeyframes(keyframes);
// Read back the new animation to see what the underlying width/height of the pseudo-element was.
const computedStyle = getComputedStyle(
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
effect.target,
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
effect.pseudoElement,
);
if (
@@ -2283,7 +2279,7 @@ export function startViewTransition(
const last = keyframes[keyframes.length - 1];
last.width = width;
last.height = height;
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
effect.setKeyframes(keyframes);
}
}
@@ -2478,7 +2474,7 @@ function animateGesture(
const reverse = rangeStart > rangeEnd;
if (timeline instanceof AnimationTimeline) {
// Native Timeline
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
targetElement.animate(keyframes, {
pseudoElement: pseudoElement,
// Set the timeline to the current gesture timeline to drive the updates.
@@ -2499,7 +2495,7 @@ function animateGesture(
});
} else {
// Custom Timeline
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
const animation = targetElement.animate(keyframes, {
pseudoElement: pseudoElement,
// We reset all easing functions to linear so that it feels like you
@@ -2556,7 +2552,6 @@ export function startGestureTransition(
const documentElement: Element = (ownerDocument.documentElement: any);
// Loop through all View Transition Animations.
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-type]
const animations = documentElement.getAnimations({subtree: true});
// First do a pass to collect all known group and new items so we can look
// up if they exist later.
@@ -2566,7 +2561,6 @@ export function startGestureTransition(
let longestDuration = 0;
for (let i = 0; i < animations.length; i++) {
const effect: KeyframeEffect = (animations[i].effect: any);
// $FlowFixMe[prop-missing]
const pseudoElement: ?string = effect.pseudoElement;
if (pseudoElement == null) {
} else if (pseudoElement.startsWith('::view-transition')) {
@@ -2598,7 +2592,6 @@ export function startGestureTransition(
continue;
}
const effect: KeyframeEffect = (anim.effect: any);
// $FlowFixMe[prop-missing]
const pseudoElement: ?string = effect.pseudoElement;
if (
pseudoElement != null &&
@@ -2658,7 +2651,7 @@ export function startGestureTransition(
}
animateGesture(
effect.getKeyframes(),
// $FlowFixMe: Always documentElement atm.
// $FlowFixMe[incompatible-type]: Always documentElement atm.
effect.target,
pseudoElement,
timeline,
@@ -2685,7 +2678,7 @@ export function startGestureTransition(
const pseudoElementName = '::view-transition-group' + groupName;
animateGesture(
[{}, {}],
// $FlowFixMe: Always documentElement atm.
// $FlowFixMe[incompatible-type]: Always documentElement atm.
effect.target,
pseudoElementName,
timeline,
@@ -2704,7 +2697,7 @@ export function startGestureTransition(
// you can swipe back again. We can prevent this by adding a paused Animation
// that never stops. This seems to keep all running Animations alive until
// we explicitly abort (or something forces the View Transition to cancel).
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-call]
const blockingAnim = documentElement.animate([{}, {}], {
pseudoElement: '::view-transition',
duration: 1,
@@ -2813,9 +2806,8 @@ ViewTransitionPseudoElement.prototype.animate = function (
duration: options,
}
: Object.assign(
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-type]
({}: KeyframeAnimationOptions),
(// $FlowFixMe[prop-missing]
{}: KeyframeAnimationOptions),
options,
);
opts.pseudoElement = this._selector;
@@ -2831,7 +2823,6 @@ ViewTransitionPseudoElement.prototype.getAnimations = function (
const selector = this._selector;
const animations = scope.getAnimations(
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-type]
{subtree: true},
);
const result = [];
@@ -4971,12 +4962,14 @@ function preinitStyle(
}
// Construct a Resource and cache it
// $FlowFixMe[incompatible-type]
resource = {
type: 'stylesheet',
instance,
count: 1,
state,
};
// $FlowFixMe[incompatible-type]
styles.set(key, resource);
return;
}

View File

@@ -98,7 +98,8 @@ export default function estimateBandwidth(): number {
// Fallback to the navigator.connection estimate if available
// $FlowFixMe[prop-missing]
if (navigator.connection) {
// $FlowFixMe
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-use]
const downlink: ?number = navigator.connection.downlink;
if (typeof downlink === 'number') {
return downlink;

View File

@@ -3366,7 +3366,7 @@ function pushImg(
// reenter this branch in a second pass for duplicate img hrefs.
promotablePreloads.delete(key);
// $FlowFixMe - Flow should understand that this is a Resource if the condition was true
// $FlowFixMe[incompatible-call] - Flow should understand that this is a Resource if the condition was true
renderState.highImagePreloads.add(resource);
}
} else if (!resumableState.imageResources.hasOwnProperty(key)) {

View File

@@ -43,11 +43,12 @@ export function defaultOnDefaultTransitionIndicator(): void | (() => void) {
}
}
// $FlowFixMe
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
navigation.addEventListener('navigate', handleNavigate);
// $FlowFixMe
// $FlowFixMe[incompatible-call]
navigation.addEventListener('navigatesuccess', handleNavigateComplete);
// $FlowFixMe
// $FlowFixMe[incompatible-call]
navigation.addEventListener('navigateerror', handleNavigateComplete);
function startFakeNavigation() {
@@ -76,11 +77,12 @@ export function defaultOnDefaultTransitionIndicator(): void | (() => void) {
return function () {
isCancelled = true;
// $FlowFixMe
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
navigation.removeEventListener('navigate', handleNavigate);
// $FlowFixMe
// $FlowFixMe[incompatible-call]
navigation.removeEventListener('navigatesuccess', handleNavigateComplete);
// $FlowFixMe
// $FlowFixMe[incompatible-call]
navigation.removeEventListener('navigateerror', handleNavigateComplete);
if (pendingResolve !== null) {
pendingResolve();

View File

@@ -97,7 +97,6 @@ function renderToReadableStream(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
): any);
// TODO: Move to sub-classing ReadableStream.
@@ -189,7 +188,6 @@ function resume(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
): any);
// TODO: Move to sub-classing ReadableStream.

View File

@@ -86,7 +86,6 @@ function prerender(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
);
@@ -179,7 +178,6 @@ function resumeAndPrerender(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
);

View File

@@ -95,7 +95,7 @@ async function executeScript(script: Element) {
}
try {
// $FlowFixMe
// $FlowFixMe[unsupported-syntax]
require(scriptSrc);
} catch (x) {
const event = new window.ErrorEvent('error', {error: x});

View File

@@ -56,7 +56,9 @@ export function createCapturedValueFromError(
stack: stack,
};
if (typeof stack === 'string') {
// $FlowFixMe[incompatible-type]
CapturedStacks.set(value, captured);
}
// $FlowFixMe[incompatible-type]
return captured;
}

View File

@@ -2224,10 +2224,12 @@ export function validateSuspenseListChildren(
enableAsyncIterableChildren &&
children.$$typeof === REACT_ELEMENT_TYPE &&
typeof children.type === 'function' &&
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[method-unbinding]
(Object.prototype.toString.call(children.type) ===
'[object GeneratorFunction]' ||
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(children.type) ===
'[object AsyncGeneratorFunction]')
) {

View File

@@ -199,7 +199,7 @@ export function commitHookEffectListMount(
addendum =
' You returned null. If your effect does not require clean ' +
'up, return undefined (or nothing).';
// $FlowFixMe (@poteto) this check is safe on arbitrary non-null/void objects
// $FlowFixMe[incompatible-type] (@poteto) this check is safe on arbitrary non-null/void objects
} else if (typeof destroy.then === 'function') {
addendum =
'\n\nIt looks like you wrote ' +
@@ -924,7 +924,8 @@ function safelyCallDestroy(
);
} else {
try {
// $FlowFixMe(incompatible-call) Already bound to resource
// $FlowFixMe[incompatible-call] Already bound to resource
// $FlowFixMe[incompatible-type]
destroy_();
} catch (error) {
captureCommitPhaseError(current, nearestMountedAncestor, error);
@@ -951,11 +952,11 @@ function commitProfiler(
onRender(
id,
phase,
// $FlowFixMe: This should be always a number in profiling mode
// $FlowFixMe[incompatible-type]: This should be always a number in profiling mode
finishedWork.actualDuration,
// $FlowFixMe: This should be always a number in profiling mode
// $FlowFixMe[incompatible-type]: This should be always a number in profiling mode
finishedWork.treeBaseDuration,
// $FlowFixMe: This should be always a number in profiling mode
// $FlowFixMe[incompatible-type]: This should be always a number in profiling mode
finishedWork.actualStartTime,
commitStartTime,
);

View File

@@ -416,9 +416,9 @@ function warnIfAsyncClientComponent(Component: Function) {
// for transpiled async functions. Neither mechanism is completely
// bulletproof but together they cover the most common cases.
const isAsyncFunction =
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(Component) === '[object AsyncFunction]' ||
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(Component) ===
'[object AsyncGeneratorFunction]';
if (isAsyncFunction) {
@@ -2745,8 +2745,8 @@ function updateEvent<Args, Return, F: (...Array<Args>) => Return>(
const hook = updateWorkInProgressHook();
const ref = hook.memoizedState;
useEffectEventImpl({ref, nextImpl: callback});
// $FlowIgnore[incompatible-return]
// $FlowIgnore[incompatible-type]
// $FlowFixMe[incompatible-return]
// $FlowFixMe[incompatible-type]
return function eventFn() {
if (isInvalidExecutionContextForEventFunction()) {
throw new Error(

View File

@@ -551,20 +551,24 @@ function readContextForConsumer<T>(
}
// This is the first dependency for this component. Create a new list.
// $FlowFixMe[incompatible-type]
lastContextDependency = contextItem;
consumer.dependencies = __DEV__
? {
? // $FlowFixMe[incompatible-type]
{
lanes: NoLanes,
firstContext: contextItem,
_debugThenableState: null,
}
: {
: // $FlowFixMe[incompatible-type]
{
lanes: NoLanes,
firstContext: contextItem,
};
consumer.flags |= NeedsPropagation;
} else {
// Append a new context item.
// $FlowFixMe[incompatible-type]
lastContextDependency = lastContextDependency.next = contextItem;
}
return value;

View File

@@ -508,9 +508,11 @@ function logComponentEffectErrored(
if (debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
// $FlowFixMe[incompatible-type]
performance.measure.bind(performance, measureName, options),
);
} else {
// $FlowFixMe[incompatible-type]
performance.measure(measureName, options);
}
performance.clearMeasures(measureName);
@@ -780,9 +782,11 @@ export function logBlockingStart(
if (debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
// $FlowFixMe[incompatible-type]
performance.measure.bind(performance, label, measureOptions),
);
} else {
// $FlowFixMe[incompatible-type]
performance.measure(label, measureOptions);
}
performance.clearMeasures(label);
@@ -886,9 +890,11 @@ export function logGestureStart(
if (debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
// $FlowFixMe[incompatible-type]
performance.measure.bind(performance, label, measureOptions),
);
} else {
// $FlowFixMe[incompatible-type]
performance.measure(label, measureOptions);
}
performance.clearMeasures(label);
@@ -1027,9 +1033,11 @@ export function logTransitionStart(
if (debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
// $FlowFixMe[incompatible-type]
performance.measure.bind(performance, label, measureOptions),
);
} else {
// $FlowFixMe[incompatible-type]
performance.measure(label, measureOptions);
}
performance.clearMeasures(label);

View File

@@ -290,6 +290,7 @@ export function suspendCommit(): void {
// This extra indirection only exists so it can handle passing
// noopSuspenseyCommitThenable through to throwException.
// TODO: Factor the thenable check out of throwException
// $FlowFixMe[incompatible-type]
suspendedThenable = noopSuspenseyCommitThenable;
throw SuspenseyCommitException;
}

View File

@@ -726,7 +726,7 @@ async function transformModuleIfNeeded(
if (sourceMappingURL) {
const sourceMapResult = await loader(
sourceMappingURL,
// $FlowFixMe
// $FlowFixMe[incompatible-type]
{
format: 'json',
conditions: [],
@@ -738,7 +738,8 @@ async function transformModuleIfNeeded(
const sourceMapString =
typeof sourceMapResult.source === 'string'
? sourceMapResult.source
: // $FlowFixMe
: // $FlowFixMe[incompatible-call]
// $FlowFixMe[extra-arg]
sourceMapResult.source.toString('utf8');
sourceMap = JSON.parse(sourceMapString);

View File

@@ -255,6 +255,8 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
const clientReference: ClientReference<any> =
registerClientReferenceImpl(({}: any), target.$$id, true);
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-variance]
const proxy = new Proxy(clientReference, proxyHandlers);
// Treat this as a resolved Promise for React's use()
@@ -302,6 +304,7 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
target.$$async,
);
Object.defineProperty((reference: any), 'name', {value: name});
// $FlowFixMe[incompatible-type]
cachedReference = target[name] = new Proxy(reference, deepProxyHandlers);
}
return cachedReference;
@@ -349,5 +352,8 @@ export function createClientModuleProxy<T>(
moduleId,
false,
);
// $FlowFixMe[incompatible-type]
// $FlowFixMe[incompatible-variance]
// $FlowFixMe[incompatible-exact]
return new Proxy(clientReference, proxyHandlers);
}

View File

@@ -51,7 +51,7 @@ export function addChunkDebugInfo(
const scriptFilename = __webpack_get_script_filename__(chunkId);
let href;
try {
// $FlowFixMe
// $FlowFixMe[incompatible-call]
href = new URL(scriptFilename, document.baseURI).href;
} catch (_) {
href = scriptFilename;
@@ -74,9 +74,9 @@ export function addChunkDebugInfo(
}
}
const value = Promise.resolve(href);
// $FlowFixMe
// $FlowFixMe[prop-missing]
value.status = 'fulfilled';
// $FlowFixMe
// $FlowFixMe[prop-missing]
value.value = {
chunkId: chunkId,
href: href,

View File

@@ -151,7 +151,6 @@ function renderToReadableStream(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
);
debugStream.pipeTo(debugChannelWritable);
@@ -174,7 +173,6 @@ function renderToReadableStream(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
);
return stream;
@@ -204,7 +202,6 @@ function prerender(
},
},
// $FlowFixMe[prop-missing] size() methods are not allowed on byte streams.
// $FlowFixMe[incompatible-type]
{highWaterMark: 0},
);
resolve({prelude: stream});

View File

@@ -129,11 +129,12 @@ function startReadingFromDebugChannelReadable(
const ws: WebSocket = (stream: any);
ws.binaryType = 'arraybuffer';
ws.addEventListener('message', event => {
// $FlowFixMe
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
onData(event.data);
});
ws.addEventListener('error', event => {
// $FlowFixMe
// $FlowFixMe[prop-missing]
onError(event.error);
});
ws.addEventListener('close', onClose);
@@ -673,7 +674,8 @@ function decodeReplyFromAsyncIterable<T>(
reportGlobalError(response, reason);
if (typeof (iterator: any).throw === 'function') {
// The iterator protocol doesn't necessarily include this but a generator do.
// $FlowFixMe should be able to pass mixed
// $FlowFixMe[incompatible-call] should be able to pass mixed
// $FlowFixMe[prop-missing]
iterator.throw(reason).then(error, error);
}
}

View File

@@ -546,8 +546,8 @@ function throwOnUseEffectEventCall() {
export function useEffectEvent<Args, Return, F: (...Array<Args>) => Return>(
callback: F,
): F {
// $FlowIgnore[incompatible-return]
// $FlowIgnore[incompatible-type]
// $FlowFixMe[incompatible-return]
// $FlowFixMe[incompatible-type]
return throwOnUseEffectEventCall;
}
@@ -631,7 +631,7 @@ function useActionState<S, P>(
const actionStateHookIndex = actionStateCounter++;
const request: Request = (currentlyRenderingRequest: any);
// $FlowIgnore[prop-missing]
// $FlowFixMe[prop-missing]
const formAction = action.$$FORM_ACTION;
if (typeof formAction === 'function') {
// This is a server action. These have additional features to enable
@@ -653,7 +653,7 @@ function useActionState<S, P>(
let state = initialState;
const componentKeyPath = (currentlyRenderingKeyPath: any);
const postbackActionState = getFormState(request);
// $FlowIgnore[prop-missing]
// $FlowFixMe[prop-missing]
const isSignatureEqual = action.$$IS_SIGNATURE_EQUAL;
if (
postbackActionState !== null &&
@@ -687,9 +687,9 @@ function useActionState<S, P>(
boundAction(payload);
};
// $FlowIgnore[prop-missing]
// $FlowFixMe[prop-missing]
if (typeof boundAction.$$FORM_ACTION === 'function') {
// $FlowIgnore[prop-missing]
// $FlowFixMe[prop-missing]
dispatch.$$FORM_ACTION = (prefix: string) => {
const metadata: ReactCustomFormAction =
boundAction.$$FORM_ACTION(prefix);

View File

@@ -1273,7 +1273,7 @@ function renderSuspenseBoundary(
}
return;
}
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
const task: RenderTask = someTask;
const prevKeyPath = task.keyPath;
@@ -2089,7 +2089,8 @@ function renderSuspenseList(
// If it's an iterator we need to continue reading where we left
// off. We can do that by reading the first few rows from the previous
// thenable state.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
// $FlowFixMe[underconstrained-implicit-instantiation]
let step = readPreviousThenableFromState();
while (step !== undefined) {
if (step.done) {
@@ -2226,7 +2227,7 @@ function renderHostElement(
props,
));
if (isPreambleContext(newContext)) {
// $FlowFixMe: Refined
// $FlowFixMe[incompatible-type]: Refined
renderPreamble(request, (task: RenderTask), segment, children);
} else {
// We use the non-destructive form because if something suspends, we still
@@ -3414,7 +3415,8 @@ function retryNode(request: Request, task: Task): void {
// If it's an iterator we need to continue reading where we left
// off. We can do that by reading the first few rows from the previous
// thenable state.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
// $FlowFixMe[underconstrained-implicit-instantiation]
let step = readPreviousThenableFromState();
while (step !== undefined) {
if (step.done) {
@@ -3704,7 +3706,7 @@ function renderChildrenArray(
if (task.replay !== null) {
replayFragment(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
children,
childIndex,
@@ -4097,7 +4099,7 @@ function renderNode(
: null;
const newTask = spawnNewSuspendedReplayTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
thenableState,
);
@@ -4133,7 +4135,7 @@ function renderNode(
: null;
const newTask = spawnNewSuspendedReplayTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
thenableState,
);
@@ -4198,7 +4200,7 @@ function renderNode(
: null;
const newTask = spawnNewSuspendedRenderTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
thenableState,
);
@@ -4233,7 +4235,7 @@ function renderNode(
: null;
const newTask = spawnNewSuspendedRenderTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
thenableState,
);
@@ -4944,13 +4946,13 @@ function retryTask(request: Request, task: Task): void {
if (segment === null) {
retryReplayTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
);
} else {
retryRenderTask(
request,
// $FlowFixMe: Refined.
// $FlowFixMe[incompatible-type]: Refined.
task,
segment,
);

View File

@@ -71,10 +71,12 @@ function decodeBoundActionMetaData(
bound: null | Promise<Array<any>>,
}>(actionResponse);
// Force it to initialize
// $FlowFixMe
// $FlowFixMe[incompatible-call]
// $FlowFixMe[incompatible-type]
refPromise.then(() => {});
if (refPromise.status !== 'fulfilled') {
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
throw refPromise.reason;
}
return refPromise.value;

View File

@@ -1144,7 +1144,7 @@ function serializeReadableStream(
// receiving side. It also implies that different chunks can be split up or merged as opposed
// to a readable stream that happens to have Uint8Array as the type which might expect it to be
// received in the same slices.
// $FlowFixMe: This is a Node.js extension.
// $FlowFixMe[prop-missing]: This is a Node.js extension.
let supportsBYOB: void | boolean = stream.supportsBYOB;
if (supportsBYOB === undefined) {
try {
@@ -1222,7 +1222,6 @@ function serializeReadableStream(
erroredTask(request, streamTask, reason);
enqueueFlush(request);
// $FlowFixMe should be able to pass mixed
reader.cancel(reason).then(error, error);
}
function abortStream() {
@@ -1241,7 +1240,6 @@ function serializeReadableStream(
erroredTask(request, streamTask, reason);
enqueueFlush(request);
}
// $FlowFixMe should be able to pass mixed
reader.cancel(reason).then(error, error);
}
@@ -1355,7 +1353,8 @@ function serializeAsyncIterable(
enqueueFlush(request);
if (typeof (iterator: any).throw === 'function') {
// The iterator protocol doesn't necessarily include this but a generator do.
// $FlowFixMe should be able to pass mixed
// $FlowFixMe[incompatible-call] should be able to pass mixed
// $FlowFixMe[prop-missing]
iterator.throw(reason).then(error, error);
}
}
@@ -1377,7 +1376,8 @@ function serializeAsyncIterable(
}
if (typeof (iterator: any).throw === 'function') {
// The iterator protocol doesn't necessarily include this but a generator do.
// $FlowFixMe should be able to pass mixed
// $FlowFixMe[incompatible-call] should be able to pass mixed
// $FlowFixMe[prop-missing]
iterator.throw(reason).then(error, error);
}
}
@@ -1577,10 +1577,10 @@ function processServerComponentReturnValue(
// tempting to try to return the value from a generator.
if (iterator === iterableChild) {
const isGeneratorComponent =
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(Component) ===
'[object GeneratorFunction]' &&
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(iterableChild) ===
'[object Generator]';
if (!isGeneratorComponent) {
@@ -1617,10 +1617,10 @@ function processServerComponentReturnValue(
// tempting to try to return the value from a generator.
if (iterator === iterableChild) {
const isGeneratorComponent =
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(Component) ===
'[object AsyncGeneratorFunction]' &&
// $FlowIgnore[method-unbinding]
// $FlowFixMe[method-unbinding]
Object.prototype.toString.call(iterableChild) ===
'[object AsyncGenerator]';
if (!isGeneratorComponent) {
@@ -3231,7 +3231,6 @@ function serializeDebugBlob(request: Request, blob: Blob): string {
const digest = '';
emitErrorChunk(request, id, digest, reason, true, null);
enqueueFlush(request);
// $FlowFixMe should be able to pass mixed
reader.cancel(reason).then(noop, noop);
}
// $FlowFixMe[incompatible-call]
@@ -3284,7 +3283,6 @@ function serializeBlob(request: Request, blob: Blob): string {
request.cacheController.signal.removeEventListener('abort', abortBlob);
erroredTask(request, newTask, reason);
enqueueFlush(request);
// $FlowFixMe should be able to pass mixed
reader.cancel(reason).then(error, error);
}
function abortBlob() {
@@ -3303,7 +3301,6 @@ function serializeBlob(request: Request, blob: Blob): string {
erroredTask(request, newTask, reason);
enqueueFlush(request);
}
// $FlowFixMe should be able to pass mixed
reader.cancel(reason).then(error, error);
}

View File

@@ -237,7 +237,7 @@ export function initAsyncDebugInfo(): void {
// If we begin before we resolve, that means that this is actually already resolved but
// the promiseResolve hook is called at the end of the execution. So we track the time
// in the before call instead.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
lastRanAwait = resolvePromiseOrAwaitNode(node, performance.now());
break;
}

View File

@@ -36,7 +36,7 @@ export function unbadgeConsole(
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// So we wouldn't have added any badge in the first place.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return null;
}
case 'assert': {

View File

@@ -27,7 +27,7 @@ export function unbadgeConsole(
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// So we wouldn't have added any badge in the first place.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return null;
}
case 'assert': {

View File

@@ -35,7 +35,7 @@ export function unbadgeConsole(
case 'table': {
// These methods cannot be colorized because they don't take a formatting string.
// So we wouldn't have added any badge in the first place.
// $FlowFixMe
// $FlowFixMe[incompatible-type]
return null;
}
case 'assert': {

View File

@@ -76,7 +76,6 @@ function writeStringChunk(destination: Destination, stringChunk: string) {
if (writtenBytes > 0) {
target = ((currentView: any): Uint8Array).subarray(writtenBytes);
}
// $FlowFixMe[prop-missing] encodeInto is not in Flow's TextEncoder libdef
const {read, written} = textEncoder.encodeInto(stringChunk, target);
writtenBytes += written;
@@ -86,7 +85,6 @@ function writeStringChunk(destination: Destination, stringChunk: string) {
(currentView: any).subarray(0, writtenBytes),
);
currentView = new Uint8Array(VIEW_SIZE);
// $FlowFixMe[prop-missing] encodeInto is not in Flow's TextEncoder libdef
writtenBytes = textEncoder.encodeInto(
stringChunk.slice(read),
(currentView: any),

View File

@@ -12,7 +12,9 @@ import type {SharedStateServer} from 'react/src/ReactSharedInternalsServer';
import * as React from 'react';
const ReactSharedInternalsServer: SharedStateServer =
// $FlowFixMe: It's defined in the one we resolve to.
// $FlowFixMe[prop-missing]: It's defined in the one we resolve to.
// $FlowFixMe[incompatible-type]
// $FlowFixMe[missing-export]
React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
if (!ReactSharedInternalsServer) {

View File

@@ -369,7 +369,7 @@ function mapChildren(
context: mixed,
): ?Array<React$Node> {
if (children == null) {
// $FlowFixMe limitation refining abstract types in Flow
// $FlowFixMe[incompatible-type] limitation refining abstract types in Flow
return children;
}
const result: Array<React$Node> = [];

View File

@@ -112,9 +112,11 @@ function lazyInitializer<T>(payload: Payload<T>): T {
const debugValue =
moduleObject == null ? undefined : moduleObject.default;
resolveDebugValue(debugValue);
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
ioInfo.value.status = 'fulfilled';
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
ioInfo.value.value = debugValue;
}
// Make the thenable introspectable
@@ -143,12 +145,15 @@ function lazyInitializer<T>(payload: Payload<T>): T {
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Hide unhandled rejections.
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
ioInfo.value.then(noop, noop);
rejectDebugValue(error);
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
ioInfo.value.status = 'rejected';
// $FlowFixMe
// $FlowFixMe[incompatible-use]
// $FlowFixMe[prop-missing]
ioInfo.value.reason = error;
}
// Make the thenable introspectable

View File

@@ -9222,12 +9222,12 @@ flatted@^3.2.9:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
flow-bin@^0.280.0:
version "0.280.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.280.0.tgz#73db532b4ea072a20a47277a38c0ab9f4f4600e6"
integrity sha512-7WHDjleRd6KDggSYovdrNSz1xMM9HKSI3ajHF3xMmWaETxx3SHnl60cclW6mPm3z+0FUVQSr7XFLiGSW3Zkq7Q==
flow-bin@^0.281.0:
version "0.281.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.281.0.tgz#be49afd6da986ba355e27d38775547b60b398e65"
integrity sha512-jgSKNLolqwtI4CZ/lTh/YKf0JAtFGTrf/8ETZkfxxyT5AYB9NfiO5KQttW0gtd63plppvw3ghyVFKLSK3TH6hg==
flow-remove-types@^2.280.0:
flow-remove-types@^2.281.0:
version "2.293.0"
resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-2.293.0.tgz#ff63c979bbf0da625cc5a9a33af546261ee23307"
integrity sha512-UoF3jXBZ3YH1SYSMq+bLchQ7HGOBykPHThCyl7FdWspCzcW1qQ2nVbkbv5fclzLOzlEZ42c8LpeliAC0tqORzA==