Skip to content

Commit e210d08

Browse files
authored
[flow] Upgrade Flow to 0.245.2 (#30919)
## Summary This PR bumps Flow all the way to the latest 0.245.2. Most of the suppressions comes from Flow v0.239.0's change to include undefined in the return of `Array.pop`. I also enabled `react.custom_jsx_typing=true` and added custom jsx typing to match the old behavior that `React.createElement` is effectively any typed. This is necessary since various builtin components like `React.Fragment` is actually symbol in the React repo instead of `React.AbstractComponent<...>`. It can be made more accurate by customizing the `React$CustomJSXFactory` type, but I will leave it to the React team to decide. ## How did you test this change? `yarn flow` for all the renderers
1 parent 984ea11 commit e210d08

File tree

24 files changed

+142
-20
lines changed

24 files changed

+142
-20
lines changed

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
6464
"fbjs-scripts": "^3.0.1",
6565
"filesize": "^6.0.1",
66-
"flow-bin": "^0.235.0",
67-
"flow-remove-types": "^2.235.0",
66+
"flow-bin": "^0.245.2",
67+
"flow-remove-types": "^2.245.2",
6868
"glob": "^7.1.6",
6969
"glob-stream": "^6.1.0",
7070
"google-closure-compiler": "^20230206.0.0",

packages/internal-test-utils/internalAct.js

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export async function act<T>(scope: () => Thenable<T>): Thenable<T> {
163163
throw thrownError;
164164
}
165165

166+
// $FlowFixMe[incompatible-return]
166167
return result;
167168
} finally {
168169
const depth = actingUpdatesScopeDepth;
@@ -271,6 +272,7 @@ export async function serverAct<T>(scope: () => Thenable<T>): Thenable<T> {
271272
throw thrownError;
272273
}
273274

275+
// $FlowFixMe[incompatible-return]
274276
return result;
275277
} finally {
276278
if (typeof process === 'object') {

packages/react-client/src/ReactFlightReplyClient.js

+3
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ export function processReply(
554554
const prefix = formFieldPrefix + refId + '_';
555555
// $FlowFixMe[prop-missing]: FormData has forEach.
556556
value.forEach((originalValue: string | File, originalKey: string) => {
557+
// $FlowFixMe[incompatible-call]
557558
data.append(prefix + originalKey, originalValue);
558559
});
559560
return serializeFormDataReference(refId);
@@ -925,6 +926,7 @@ function defaultEncodeFormAction(
925926
const prefixedData = new FormData();
926927
// $FlowFixMe[prop-missing]
927928
encodedFormData.forEach((value: string | File, key: string) => {
929+
// $FlowFixMe[incompatible-call]
928930
prefixedData.append('$ACTION_' + identifierPrefix + ':' + key, value);
929931
});
930932
data = prefixedData;
@@ -1153,6 +1155,7 @@ const FunctionBind = Function.prototype.bind;
11531155
const ArraySlice = Array.prototype.slice;
11541156
function bind(this: Function): Function {
11551157
// $FlowFixMe[unsupported-syntax]
1158+
// $FlowFixMe[prop-missing]
11561159
const newFn = FunctionBind.apply(this, arguments);
11571160
const reference = knownServerReferences.get(this);
11581161
if (reference) {

packages/react-debug-tools/src/ReactDebugHooks.js

+1
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ function buildTree(
10331033
}
10341034
// Pop back the stack as many steps as were not common.
10351035
for (let j = prevStack.length - 1; j > commonSteps; j--) {
1036+
// $FlowFixMe[incompatible-type]
10361037
levelChildren = stackOfChildren.pop();
10371038
}
10381039
}

packages/react-devtools-shared/src/backend/profilingHooks.js

+3
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,19 @@ export function createProfilingHooks({
274274
}
275275

276276
const top = currentReactMeasuresStack.pop();
277+
// $FlowFixMe[incompatible-type]
277278
if (top.type !== type) {
278279
console.error(
279280
'Unexpected type "%s" completed at %sms before "%s" completed.',
280281
type,
281282
currentTime,
283+
// $FlowFixMe[incompatible-use]
282284
top.type,
283285
);
284286
}
285287

286288
// $FlowFixMe[cannot-write] This property should not be writable outside of this function.
289+
// $FlowFixMe[incompatible-use]
287290
top.duration = currentTime - top.timestamp;
288291

289292
if (currentTimelineData) {

packages/react-devtools-shared/src/backend/utils.js

+2
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,12 @@ export function formatConsoleArgumentsToSingleString(
299299
if (args.length) {
300300
const REGEXP = /(%?)(%([jds]))/g;
301301

302+
// $FlowFixMe[incompatible-call]
302303
formatted = formatted.replace(REGEXP, (match, escaped, ptn, flag) => {
303304
let arg = args.shift();
304305
switch (flag) {
305306
case 's':
307+
// $FlowFixMe[unsafe-addition]
306308
arg += '';
307309
break;
308310
case 'd':

packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ export default class Overlay {
194194

195195
while (this.rects.length > elements.length) {
196196
const rect = this.rects.pop();
197+
// $FlowFixMe[incompatible-use]
197198
rect.remove();
198199
}
199200
if (elements.length === 0) {

packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js

+4
Original file line numberDiff line numberDiff line change
@@ -391,18 +391,22 @@ const __printTree = (commitTree: CommitTree) => {
391391
const id = queue.shift();
392392
const depth = queue.shift();
393393

394+
// $FlowFixMe[incompatible-call]
394395
const node = nodes.get(id);
395396
if (node == null) {
397+
// $FlowFixMe[incompatible-type]
396398
throw Error(`Could not find node with id "${id}" in commit tree`);
397399
}
398400

399401
console.log(
402+
// $FlowFixMe[incompatible-call]
400403
`${'•'.repeat(depth)}${node.id}:${node.displayName || ''} ${
401404
node.key ? `key:"${node.key}"` : ''
402405
} (${node.treeBaseDuration})`,
403406
);
404407

405408
node.children.forEach(childID => {
409+
// $FlowFixMe[unsafe-addition]
406410
queue.push(childID, depth + 1);
407411
});
408412
}

packages/react-devtools-shared/src/devtools/views/utils.js

+4
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,14 @@ export function serializeHooksForCopy(hooks: HooksTree | null): string {
142142
const current = queue.pop();
143143

144144
// These aren't meaningful
145+
// $FlowFixMe[incompatible-use]
145146
delete current.id;
147+
// $FlowFixMe[incompatible-use]
146148
delete current.isStateEditable;
147149

150+
// $FlowFixMe[incompatible-use]
148151
if (current.subHooks.length > 0) {
152+
// $FlowFixMe[incompatible-use]
149153
queue.push(...current.subHooks);
150154
}
151155
}

packages/react-devtools-shared/src/hook.js

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ export function installHook(target: any): DevToolsHook | null {
532532
const startStackFrame = openModuleRangesStack.pop();
533533
const stopStackFrame = getTopStackFrameString(error);
534534
if (stopStackFrame !== null) {
535+
// $FlowFixMe[incompatible-call]
535536
moduleRanges.push([startStackFrame, stopStackFrame]);
536537
}
537538
}

packages/react-devtools-shared/src/utils.js

+2
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ export function parseElementDisplayNameFromBackend(
475475
if (displayName.indexOf('(') >= 0) {
476476
const matches = displayName.match(/[^()]+/g);
477477
if (matches != null) {
478+
// $FlowFixMe[incompatible-type]
478479
displayName = matches.pop();
479480
hocDisplayNames = matches;
480481
}
@@ -485,6 +486,7 @@ export function parseElementDisplayNameFromBackend(
485486
}
486487

487488
return {
489+
// $FlowFixMe[incompatible-return]
488490
formattedDisplayName: displayName,
489491
hocDisplayNames,
490492
compiledWithForget: false,

packages/react-devtools-timeline/src/import-worker/preprocessData.js

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ function markWorkCompleted(
202202
);
203203
}
204204

205+
// $FlowFixMe[incompatible-use]
205206
const {measure, startTime} = stack.pop();
206207
if (!measure) {
207208
console.error('Could not find matching measure for type "%s".', type);

packages/react-dom/src/client/ReactDOMClientFB.js

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ function flushSyncFromReconciler<R>(fn: (() => R) | void): R | void {
100100
);
101101
}
102102
}
103+
// $FlowFixMe[incompatible-call]
103104
return flushSyncWithoutWarningIfAlreadyRendering(fn);
104105
}
105106

packages/react-native-renderer/src/ReactNativeTypes.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ export type ReactNativeType = {
233233
): ?ElementRef<ElementType>,
234234
unmountComponentAtNode(containerTag: number): void,
235235
unmountComponentAtNodeAndRemoveContainer(containerTag: number): void,
236-
unstable_batchedUpdates: <T>(fn: (T) => void, bookkeeping: T) => void,
237-
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsType,
236+
+unstable_batchedUpdates: <T>(fn: (T) => void, bookkeeping: T) => void,
237+
+__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsType,
238238
...
239239
};
240240

packages/react-server-dom-esm/src/ReactFlightESMReferences.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const FunctionBind = Function.prototype.bind;
4949
// $FlowFixMe[method-unbinding]
5050
const ArraySlice = Array.prototype.slice;
5151
function bind(this: ServerReference<any>): any {
52-
// $FlowFixMe[unsupported-syntax]
52+
// $FlowFixMe[prop-missing]
5353
const newFn = FunctionBind.apply(this, arguments);
5454
if (this.$$typeof === SERVER_REFERENCE_TAG) {
5555
if (__DEV__) {

packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const FunctionBind = Function.prototype.bind;
6363
// $FlowFixMe[method-unbinding]
6464
const ArraySlice = Array.prototype.slice;
6565
function bind(this: ServerReference<any>): any {
66-
// $FlowFixMe[unsupported-syntax]
66+
// $FlowFixMe[prop-missing]
6767
const newFn = FunctionBind.apply(this, arguments);
6868
if (this.$$typeof === SERVER_REFERENCE_TAG) {
6969
if (__DEV__) {

packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const FunctionBind = Function.prototype.bind;
6464
const ArraySlice = Array.prototype.slice;
6565
function bind(this: ServerReference<any>): any {
6666
// $FlowFixMe[unsupported-syntax]
67+
// $FlowFixMe[prop-missing]
6768
const newFn = FunctionBind.apply(this, arguments);
6869
if (this.$$typeof === SERVER_REFERENCE_TAG) {
6970
if (__DEV__) {

packages/react-server/src/ReactFlightActionServer.js

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export function decodeAction<T>(
9393
// $FlowFixMe[prop-missing]
9494
body.forEach((value: string | File, key: string) => {
9595
if (!key.startsWith('$ACTION_')) {
96+
// $FlowFixMe[incompatible-call]
9697
formData.append(key, value);
9798
return;
9899
}

packages/react-server/src/ReactFlightReplyServer.js

+1
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ function parseModelString(
978978
// $FlowFixMe[prop-missing] FormData has forEach on it.
979979
backingFormData.forEach((entry: File | string, entryKey: string) => {
980980
if (entryKey.startsWith(formPrefix)) {
981+
// $FlowFixMe[incompatible-call]
981982
data.append(entryKey.slice(formPrefix.length), entry);
982983
}
983984
});

packages/react-test-renderer/src/ReactTestRenderer.js

+4
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,14 @@ function flatten(arr) {
166166
const stack = [{i: 0, array: arr}];
167167
while (stack.length) {
168168
const n = stack.pop();
169+
// $FlowFixMe[incompatible-use]
169170
while (n.i < n.array.length) {
171+
// $FlowFixMe[incompatible-use]
170172
const el = n.array[n.i];
173+
// $FlowFixMe[incompatible-use]
171174
n.i += 1;
172175
if (isArray(el)) {
176+
// $FlowFixMe[incompatible-call]
173177
stack.push(n);
174178
stack.push({i: 0, array: el});
175179
break;

packages/scheduler/src/SchedulerMinHeap.js

+2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export function pop<T: Node>(heap: Heap<T>): T | null {
3131
const first = heap[0];
3232
const last = heap.pop();
3333
if (last !== first) {
34+
// $FlowFixMe[incompatible-type]
3435
heap[0] = last;
36+
// $FlowFixMe[incompatible-call]
3537
siftDown(heap, last, 0);
3638
}
3739
return first;

scripts/flow/config/flowconfig

+3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131

3232
[lints]
3333
untyped-type-import=error
34+
internal-type=off
35+
deprecated-type=off
3436

3537
[options]
3638
munge_underscores=false
39+
react.custom_jsx_typing=true
3740

3841
# Substituted by createFlowConfig.js:
3942
%REACT_RENDERER_FLOW_OPTIONS%

scripts/flow/environment.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ declare const AggregateError: Class<Error>;
2626
declare const FinalizationRegistry: any;
2727

2828
declare module 'create-react-class' {
29-
declare const exports: React$CreateClass;
29+
declare const exports: $FlowFixMe;
3030
}
3131

3232
declare interface ConsoleTask {
@@ -46,6 +46,8 @@ declare opaque type React$Element<
4646
+ref: any,
4747
};
4848

49+
declare type React$CustomJSXFactory = any;
50+
4951
declare const trustedTypes: {
5052
isHTML: (value: any) => boolean,
5153
isScript: (value: any) => boolean,

0 commit comments

Comments
 (0)